1
0
mirror of https://github.com/aportelli/LatAnalyze.git synced 2025-04-11 03:20:46 +01:00

Merge branch 'release/3.1'

This commit is contained in:
Antonin Portelli 2016-04-13 12:47:07 +01:00
commit 4b2d070e02
102 changed files with 4009 additions and 2758 deletions

3
.gitignore vendored
View File

@ -27,3 +27,6 @@ lib/*Parser.hpp
# Eigen headers # Eigen headers
lib/Eigen/* lib/Eigen/*
lib/eigen_files.mk lib/eigen_files.mk
# CI builds
ci-scripts/local/*

84
.travis.yml Normal file
View File

@ -0,0 +1,84 @@
language: cpp
notifications:
email: false
slack: ukqcd:mQLXCtz8D2cg89xT8j1a4wku
cache:
directories:
- ci-scripts/local
matrix:
include:
- os: osx
osx_image: xcode7.2
compiler: clang
- os: osx
osx_image: xcode7.2
compiler: gcc
env: VERSION=-5
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.9
- libgsl0-dev
- flex
- bison
env: VERSION=-4.9
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-5
- libgsl0-dev
- flex
- bison
env: VERSION=-5
- compiler: clang
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.6
packages:
- clang-3.6
- libgsl0-dev
- flex
- bison
env: VERSION=-3.6
- compiler: clang
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
packages:
- clang-3.7
- libgsl0-dev
- flex
- bison
env: VERSION=-3.7
before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install gsl; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install bison flex; export PATH="/usr/local/opt/flex/bin:/usr/local/opt/bison/bin:$PATH"; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]] && [[ "$CC" == "gcc" ]]; then brew install gcc5; fi
install:
- export LATDIR=`pwd`
- export CC=$CC$VERSION
- export CXX=$CXX$VERSION
- cd ci-scripts
- ./install-deps.sh `pwd`/local
- cd ..
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export LD_LIBRARY_PATH=${LATDIR}/ci-scripts/local/lib:$LD_LIBRARY_PATH; fi
script:
- cd ci-scripts
- ./install-latan.sh `pwd`/local $TRAVIS_OS_NAME

74
Readme.md Normal file
View File

@ -0,0 +1,74 @@
# LatAnalyze
Contributors: Antonin Portelli, Matt Spraggs
License: GNU General Public License v3
<table>
<tr>
<td>Last stable release</td>
<td><a href="https://travis-ci.org/aportelli/LatAnalyze">
<img src="https://travis-ci.org/aportelli/LatAnalyze.svg?branch=master"></a>
</td>
</tr>
<tr>
<td>Development branch</td>
<td><a href="https://travis-ci.org/aportelli/LatAnalyze">
<img src="https://travis-ci.org/aportelli/LatAnalyze.svg?branch=develop"></a>
</td>
</tr>
</table>
## Description
LatAnalyze is a C++11 library for statistical data analysis based on bootstrap
resampling. It has been written with lattice QCD data analysis in mind (hence
the name), but its features are not lattice specific and can be used more general statistical context.
Sadly a proper documentation was never written, but some comprehensive examples covering most features can be found in the `examples` directory.
The main features are the following:
* Array and matrix types with fast arithmetic operations based on [Eigen](http://eigen.tuxfamily.org).
* High-level types for bootstrap sample manipulation (including various statistical estimators and histogramming).
* Mathematical expression parser for runtime defined functions.
* Data I/O in ASCII and HDF5 (optional).
* High-level wrappers to minimisation routines from the [GSL](http://www.gnu.org/software/gsl/), [Minuit](http://seal.web.cern.ch/seal/snapshot/work-packages/mathlibs/minuit/) (optional) and [NLopt](http://ab-initio.mit.edu/wiki/index.php/NLopt).
* Non-linear regression with error on independent variables (through total least squares).
* High-level wrappers to numerical integrator and non-linear solver from the [GSL](http://www.gnu.org/software/gsl/).
* High-level functional types for function of model. General functions can be defined from C pointers, C++ objects, strings of mathematical expressions or tabulated data.
* High-level plotting functions based on [gnuplot](http://www.gnuplot.info), with the possibility of generating and saving plot scripts.
## Installation
The head of the `master` branch always points to the latest stable release. The `develop` branch is the main unstable branch of LatAnalyze.
LatAnalyze is written in C++11 and requires a rather recent C++ compiler to be built. It has been successfully built on various Linux and OS X platforms using clang (from 3.7), GCC (from 4.9) and the Intel C++ compiler (2016).
The strict dependencies are the [GSL](http://www.gnu.org/software/gsl/) and [LatCore](https://github.com/aportelli/LatCore).
Additionally, autoconf, automake (from 1.11), libtool, bison (from 3.0) and flex are necessary to build the library. Unless you use a very exotic system, these tools are standard on any Unix platform and should be already present or easy to install through a package manager.
Optional dependencies are [HDF5](https://www.hdfgroup.org/HDF5/) (built with C++ support), [Minuit](http://seal.web.cern.ch/seal/snapshot/work-packages/mathlibs/minuit/) and [NLopt](http://ab-initio.mit.edu/wiki/index.php/NLopt).
For a quick installation with all possible extensions execute:
```
./install-latan.sh <prefix> {osx|linux}
```
in the `ci-scripts` directory where `<prefix>` is where you want LatAnalyze (and its dependencies) to be installed and `{osx|linux}` should be the name of your OS. This script will automatically download, build and install LatCore, HDF5, Minuit and NLopt. It is assumed that the GSL can be found in a standard location (_e.g._ it has been installed through a package manager for Linux and is present in `/usr/local` for OS X).
For a more customised installation, one first needs to generate the build system by running `./bootstrap.sh` in the root directory. Then the library can be built and installed through the usual GNU mantra `./configure <options> && make && make install`. Use `./configure --help` to obtain a list of possible options for `./configure`. Because Eigen expressions rely a lot on inlining and compiler optimisations it is strongly recommended to set the `CXXFLAGS` variable to `-O3 -march=native -mtune=native`.
## History
#### v3.1
Additions:
* Wrappers to NLopt and GSL minimisers.
* Command-line tool to plot the correlation heatmap of a boostrap sample file.
* I/O functions for `DSample` type.
Changes:
* Internal random generator removed (obsolete because of C++11 pseudo-random generators).
* Fit interface and `XY*Data` classes rewritten from scratch for improved flexibility and performance.
Fixes:
* **Loads** of portability and compatibility fixes and [CI with Travis](https://travis-ci.org/aportelli/LatAnalyze).
#### v3.0
Commit `7b4f2884a5e99bbfab4d4bd7623f609a55403c39`.
First 'stable' version of LatAnalyze in C++. The v2.0 refers to the [C version](https://github.com/aportelli/LatAnalyze-legacy) and v1.0 to an old undistributed version.
**This version compiles fine on OS X with clang but does have many portability issues to other platforms/compilers, v3.1 is the first real release.**

16
ci-scripts/install-deps.sh Executable file
View File

@ -0,0 +1,16 @@
#!/usr/bin/env bash
if (( $# != 1 )); then
echo "usage: `basename $0` <prefix> {osx|linux}" 1>&2
exit 1
fi
PREFIX=$1
set -ex
mkdir -p local/build
for d in nlopt minuit hdf5; do
if [ ! -e local/.built.${d} ]; then
./install-${d}.sh ${PREFIX}
fi
done
./install-latcore.sh ${PREFIX}

23
ci-scripts/install-hdf5.sh Executable file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env bash
NAME='hdf5-1.8.16'
if (( $# != 1 )); then
echo "usage: `basename $0` <prefix> {osx|linux}" 1>&2
exit 1
fi
PREFIX=$1
set -ex
INITDIR=`pwd`
cd local/build
wget http://www.hdfgroup.org/ftp/HDF5/current/src/${NAME}.tar.gz
tar -xzvf ${NAME}.tar.gz
mkdir ${NAME}/build
cd ${NAME}/build
../configure --prefix=${PREFIX} --enable-cxx
make -j4
make install
cd ${INITDIR}/local
touch .built.hdf5
cd ${INITDIR}

19
ci-scripts/install-latan.sh Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env bash
if (( $# != 2 )); then
echo "usage: `basename $0` <prefix> {osx|linux}" 1>&2
exit 1
fi
PREFIX=$1
OS=$2
set -ex
./install-deps.sh ${PREFIX}
cd ..
./bootstrap.sh
mkdir -p build
cd build
if [[ "$OS" == "osx" ]]; then EXTRA_FLAGS='--with-gsl=/usr/local'; fi
../configure --prefix=$PREFIX --with-minuit=$PREFIX --with-nlopt=$PREFIX --with-latcore=$PREFIX --with-hdf5=$PREFIX $EXTRA_FLAGS CXXFLAGS='-O3 -march=native -mtune=native'
make -j4
make install

25
ci-scripts/install-latcore.sh Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/env bash
if (( $# != 1 )); then
echo "usage: `basename $0` <prefix> {osx|linux}" 1>&2
exit 1
fi
PREFIX=$1
set -ex
INITDIR=`pwd`
cd local/build
if [ -d LatCore ]; then
cd LatCore
git pull origin master
else
git clone https://github.com/aportelli/LatCore.git
mkdir LatCore/build
cd LatCore
./bootstrap.sh
fi
cd build
../configure --prefix=${PREFIX}
make -j4
make install
cd ${INITDIR}

23
ci-scripts/install-minuit.sh Executable file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env bash
NAME='Minuit2-5.34.14'
if (( $# != 1 )); then
echo "usage: `basename $0` <prefix> {osx|linux}" 1>&2
exit 1
fi
PREFIX=$1
set -ex
INITDIR=`pwd`
cd local/build
wget http://www.cern.ch/mathlibs/sw/5_34_14/Minuit2/${NAME}.tar.gz
tar -xzvf ${NAME}.tar.gz
mkdir -p ${NAME}/build
cd ${NAME}/build
../configure --prefix=${PREFIX} --disable-openmp
make -j4
make install
cd ${INITDIR}/local
touch .built.minuit
cd ${INITDIR}

23
ci-scripts/install-nlopt.sh Executable file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env bash
NAME='nlopt-2.4.2'
if (( $# != 1 )); then
echo "usage: `basename $0` <prefix> {osx|linux}" 1>&2
exit 1
fi
PREFIX=$1
set -ex
INITDIR=`pwd`
cd local/build
wget http://ab-initio.mit.edu/nlopt/${NAME}.tar.gz
tar -xzvf ${NAME}.tar.gz
mkdir -p ${NAME}/build
cd ${NAME}/build
../configure --prefix=${PREFIX} --with-cxx --without-guile --without-python --without-octave --without-matlab --with-pic
make -j4
make install
cd ${INITDIR}/local
touch .built.nlopt
cd ${INITDIR}

View File

@ -2,16 +2,17 @@
# Initialization # Initialization
AC_PREREQ([2.63]) AC_PREREQ([2.63])
AC_INIT([LatAnalyze],[3.0],[antonin.portelli@me.com],[LatAnalyze]) AC_INIT([LatAnalyze],[3.1-rc],[antonin.portelli@me.com],[LatAnalyze])
AC_CONFIG_AUX_DIR([.buildutils]) AC_CONFIG_AUX_DIR([.buildutils])
AC_CONFIG_SRCDIR([lib/Global.cpp]) AC_CONFIG_SRCDIR([lib/Global.cpp])
AC_CONFIG_SRCDIR([utils/sample_read.cpp]) AC_CONFIG_SRCDIR([utils/sample_read.cpp])
AC_CONFIG_SRCDIR([examples/exMathInterpreter.cpp]) AC_CONFIG_SRCDIR([examples/exMathInterpreter.cpp])
AC_CONFIG_MACRO_DIR([.buildutils/m4]) AC_CONFIG_MACRO_DIR([.buildutils/m4])
AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AM_INIT_AUTOMAKE([1.11 -Wall -Werror foreign])
AM_SILENT_RULES([yes]) AM_SILENT_RULES([yes])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AM_CONDITIONAL([HAVE_AM_MINOR_LE_11],
[test `automake --version | grep automake | awk -F '.' '{print $2}'` -le 11])
# Checks for programs # Checks for programs
AC_PROG_CXX AC_PROG_CXX
AC_PROG_AWK AC_PROG_AWK
@ -27,37 +28,34 @@ m4_ifdef([AM_PROG_AR],[AM_PROG_AR])
LT_INIT LT_INIT
# Options # Options
AC_ARG_ENABLE([SSE],
[AS_HELP_STRING([--enable-SSE],
[compiles SSE version of ranlux random generator])],
[AC_DEFINE([HAVE_SSE],
[1],
[Define to 1 if your CPU support SSE instructions.])])
AC_ARG_WITH([gsl], AC_ARG_WITH([gsl],
[AS_HELP_STRING([--with-gsl=prefix], [AS_HELP_STRING([--with-gsl=prefix],
[try this for a non-standard install prefix of the GSL library])], [try this for a non-standard install prefix of the GSL library])],
[AM_CFLAGS="$AM_CFLAGS -I$with_gsl/include"]
[AM_CXXFLAGS="$AM_CXXFLAGS -I$with_gsl/include"] [AM_CXXFLAGS="$AM_CXXFLAGS -I$with_gsl/include"]
[AM_LDFLAGS="$AM_LDFLAGS -L$with_gsl/lib"]) [AM_LDFLAGS="$AM_LDFLAGS -L$with_gsl/lib"])
AC_ARG_WITH([Minuit2], AC_ARG_WITH([minuit],
[AS_HELP_STRING([--with-Minuit2=prefix], [AS_HELP_STRING([--with-minuit=prefix],
[try this for a non-standard install prefix of the Minuit2 library])], [try this for a non-standard install prefix of the Minuit2 library])],
[AM_CFLAGS="$AM_CFLAGS -I$with_Minuit2/include"] [AM_CXXFLAGS="$AM_CXXFLAGS -I$with_minuit/include"]
[AM_CXXFLAGS="$AM_CXXFLAGS -I$with_Minuit2/include"] [AM_LDFLAGS="$AM_LDFLAGS -L$with_minuit/lib"])
[AM_LDFLAGS="$AM_LDFLAGS -L$with_Minuit2/lib"]) AC_ARG_WITH([nlopt],
AC_ARG_WITH([LatCore], [AS_HELP_STRING([--with-nlopt=prefix],
[AS_HELP_STRING([--with-LatCore=prefix], [try this for a non-standard install prefix of the NLopt library])],
[AM_CXXFLAGS="$AM_CXXFLAGS -I$with_nlopt/include"]
[AM_LDFLAGS="$AM_LDFLAGS -L$with_nlopt/lib"])
AC_ARG_WITH([hdf5],
[AS_HELP_STRING([--with-hdf5=prefix],
[try this for a non-standard install prefix of the HDF5 library])],
[AM_CXXFLAGS="$AM_CXXFLAGS -I$with_hdf5/include"]
[AM_LDFLAGS="$AM_LDFLAGS -L$with_hdf5/lib"])
AC_ARG_WITH([latcore],
[AS_HELP_STRING([--with-latcore=prefix],
[use this option for a non-standard install prefix of the LatCore library])], [use this option for a non-standard install prefix of the LatCore library])],
[AM_CXXFLAGS="$AM_CXXFLAGS -I$with_LatCore/include"] [AM_CXXFLAGS="$AM_CXXFLAGS -I$with_latcore/include"]
[AM_LDFLAGS="$AM_LDFLAGS -L$with_LatCore/lib"]) [AM_LDFLAGS="$AM_LDFLAGS -L$with_latcore/lib"])
AX_LIB_HDF5() CFLAGS="$AM_CFLAGS $CFLAGS"
if test x$with_hdf5 = xno; then CXXFLAGS="$AM_CXXFLAGS $CXXFLAGS"
AC_MSG_ERROR([HDF5 library not found]) LDFLAGS="$AM_LDFLAGS $LDFLAGS"
fi
CFLAGS="$AM_CFLAGS $HDF5_CFLAGS $CFLAGS"
CXXFLAGS="$AM_CXXFLAGS $HDF5_CPPFLAGS $CXXFLAGS"
LDFLAGS="$AM_LDFLAGS $HDF5_LDFLAGS $LDFLAGS"
LIBS="$LIBS $HDF5_LIBS -lhdf5_cpp"
# Get compilers informations # Get compilers informations
AX_COMPILER_VENDOR AX_COMPILER_VENDOR
@ -84,8 +82,20 @@ AC_CHECK_LIB([m],[cos],[],[AC_MSG_ERROR([libm library not found])])
AC_CHECK_LIB([gslcblas],[cblas_dgemm],[], AC_CHECK_LIB([gslcblas],[cblas_dgemm],[],
[AC_MSG_ERROR([GSL CBLAS library not found])]) [AC_MSG_ERROR([GSL CBLAS library not found])])
AC_CHECK_LIB([gsl],[gsl_blas_dgemm],[],[AC_MSG_ERROR([GSL library not found])]) AC_CHECK_LIB([gsl],[gsl_blas_dgemm],[],[AC_MSG_ERROR([GSL library not found])])
AC_CHECK_LIB([LatCore],[_ZN7LatCore12testFunctionEv],[], AC_CHECK_LIB([nlopt_cxx],[nlopt_create],
[AC_MSG_ERROR([LatCore library not found])]) [AC_DEFINE([HAVE_NLOPT],
[1],
[Define to 1 if you have the `NLopt' library (-lnlopt_cxx).])]
[have_nlopt=true]
[LIBS="$LIBS -lnlopt_cxx"],[])
AM_CONDITIONAL([HAVE_NLOPT], [test x$have_nlopt = xtrue])
AC_CHECK_LIB([hdf5_cpp],[H5Fopen],
[AC_DEFINE([HAVE_HDF5],
[1],
[Define to 1 if you have the `HDF5' library (-lhdf5_cpp).])]
[have_hdf5=true]
[LIBS="$LIBS -lhdf5_cpp -lhdf5"],[],[-lhdf5])
AM_CONDITIONAL([HAVE_HDF5], [test x$have_hdf5 = xtrue])
SAVED_LDFLAGS=$LDFLAGS SAVED_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -lMinuit2" LDFLAGS="$LDFLAGS -lMinuit2"
AC_MSG_CHECKING([for ROOT::Minuit2::BasicMinimumError in -lMinuit2]); AC_MSG_CHECKING([for ROOT::Minuit2::BasicMinimumError in -lMinuit2]);
@ -102,6 +112,17 @@ AC_LINK_IFELSE(
[AC_MSG_RESULT([no])]) [AC_MSG_RESULT([no])])
AM_CONDITIONAL([HAVE_MINUIT], [test x$have_minuit = xtrue]) AM_CONDITIONAL([HAVE_MINUIT], [test x$have_minuit = xtrue])
LDFLAGS=$SAVED_LDFLAGS LDFLAGS=$SAVED_LDFLAGS
SAVED_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -lLatCore"
AC_MSG_CHECKING([for LatCore::XmlReader in -lLatCore]);
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([#include <LatCore/XmlReader.hpp>],
[LatCore::XmlReader dummy()])],
[LIBS="$LIBS -lLatCore"]
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])]
[AC_MSG_ERROR([LatCore library not found])])
LDFLAGS=$SAVED_LDFLAGS
# Checks for header files. # Checks for header files.
AC_HEADER_STDC AC_HEADER_STDC
@ -112,3 +133,18 @@ AC_SUBST([AM_LDFLAGS])
AC_CONFIG_FILES([Makefile lib/Makefile utils/Makefile examples/Makefile]) AC_CONFIG_FILES([Makefile lib/Makefile utils/Makefile examples/Makefile])
AC_OUTPUT AC_OUTPUT
echo "*********************************************"
echo "* ${PACKAGE_NAME} v${VERSION}" build options
echo "*********************************************"
echo "* C++ compiler : $CXX"
echo "* HDF5 support : `test x$HAVE_HDF5_TRUE = 'x' && echo yes \
|| echo no`"
echo "* Minuit minimizers: `test x$HAVE_MINUIT_TRUE = 'x' && echo yes \
|| echo no`"
echo "* NLopt minimizers : `test x$HAVE_NLOPT_TRUE = 'x' && echo yes \
|| echo no`"
echo "*********************************************"

View File

@ -1,80 +1,71 @@
if CC_GNU
COM_CFLAGS = -Wall -W -pedantic
else
if CC_INTEL
COM_CFLAGS = -Wall
endif
endif
if CXX_GNU if CXX_GNU
COM_CXXFLAGS = -Wall -W -pedantic COM_CXXFLAGS = -Wall -W -pedantic -Wno-deprecated-declarations
else else
if CXX_INTEL if CXX_INTEL
COM_CXXFLAGS = -Wall COM_CXXFLAGS = -wd1682 -Wall
endif endif
endif endif
noinst_PROGRAMS = \ noinst_PROGRAMS = \
exCompiledDoubleFunction\ exCompiledDoubleFunction\
exDerivative \ exDerivative \
exFit \
exFitSample \
exIntegrator \ exIntegrator \
exInterp \ exInterp \
exMat \ exMat \
exMathInterpreter \ exMathInterpreter \
exMin \
exPlot \ exPlot \
exRand \ exRand \
exRootFinder exRootFinder
if HAVE_MINUIT exCompiledDoubleFunction_SOURCES = exCompiledDoubleFunction.cpp
noinst_PROGRAMS += exFit exMin exCompiledDoubleFunction_CXXFLAGS = $(COM_CXXFLAGS)
endif exCompiledDoubleFunction_LDFLAGS = -L../lib/.libs -lLatAnalyze
exCompiledDoubleFunction_SOURCES = exCompiledDoubleFunction.cpp exDerivative_SOURCES = exDerivative.cpp
exCompiledDoubleFunction_CFLAGS = -g -O2 exDerivative_CXXFLAGS = $(COM_CXXFLAGS)
exCompiledDoubleFunction_LDFLAGS = -L../lib/.libs -lLatAnalyze exDerivative_LDFLAGS = -L../lib/.libs -lLatAnalyze
exDerivative_SOURCES = exDerivative.cpp exFit_SOURCES = exFit.cpp
exDerivative_CFLAGS = -g -O2 exFit_CXXFLAGS = $(COM_CXXFLAGS)
exDerivative_LDFLAGS = -L../lib/.libs -lLatAnalyze exFit_LDFLAGS = -L../lib/.libs -lLatAnalyze
if HAVE_MINUIT exFitSample_SOURCES = exFitSample.cpp
exFit_SOURCES = exFit.cpp exFitSample_CXXFLAGS = $(COM_CXXFLAGS)
exFit_CFLAGS = -g -O2 exFitSample_LDFLAGS = -L../lib/.libs -lLatAnalyze
exFit_LDFLAGS = -L../lib/.libs -lLatAnalyze
endif
exInterp_SOURCES = exInterp.cpp exInterp_SOURCES = exInterp.cpp
exInterp_CFLAGS = -g -O2 exInterp_CXXFLAGS = $(COM_CXXFLAGS)
exInterp_LDFLAGS = -L../lib/.libs -lLatAnalyze exInterp_LDFLAGS = -L../lib/.libs -lLatAnalyze
exIntegrator_SOURCES = exIntegrator.cpp exIntegrator_SOURCES = exIntegrator.cpp
exIntegrator_CFLAGS = -g -O2 exIntegrator_CXXFLAGS = $(COM_CXXFLAGS)
exIntegrator_LDFLAGS = -L../lib/.libs -lLatAnalyze exIntegrator_LDFLAGS = -L../lib/.libs -lLatAnalyze
exMat_SOURCES = exMat.cpp exMat_SOURCES = exMat.cpp
exMat_CFLAGS = -g -O2 exMat_CXXFLAGS = $(COM_CXXFLAGS)
exMat_LDFLAGS = -L../lib/.libs -lLatAnalyze exMat_LDFLAGS = -L../lib/.libs -lLatAnalyze
if HAVE_MINUIT exMin_SOURCES = exMin.cpp
exMin_SOURCES = exMin.cpp exMin_CXXFLAGS = $(COM_CXXFLAGS)
exMin_CFLAGS = -g -O2 exMin_LDFLAGS = -L../lib/.libs -lLatAnalyze
exMin_LDFLAGS = -L../lib/.libs -lLatAnalyze
endif
exMathInterpreter_SOURCES = exMathInterpreter.cpp exMathInterpreter_SOURCES = exMathInterpreter.cpp
exMathInterpreter_CFLAGS = -g -O2 exMathInterpreter_CXXFLAGS = $(COM_CXXFLAGS)
exMathInterpreter_LDFLAGS = -L../lib/.libs -lLatAnalyze exMathInterpreter_LDFLAGS = -L../lib/.libs -lLatAnalyze
exPlot_SOURCES = exPlot.cpp exPlot_SOURCES = exPlot.cpp
exPlot_CFLAGS = -g -O2 exPlot_CXXFLAGS = $(COM_CXXFLAGS)
exPlot_LDFLAGS = -L../lib/.libs -lLatAnalyze exPlot_LDFLAGS = -L../lib/.libs -lLatAnalyze
exRand_SOURCES = exRand.cpp exRand_SOURCES = exRand.cpp
exRand_CFLAGS = -g -O2 exRand_CXXFLAGS = $(COM_CXXFLAGS)
exRand_LDFLAGS = -L../lib/.libs -lLatAnalyze exRand_LDFLAGS = -L../lib/.libs -lLatAnalyze
exRootFinder_SOURCES = exRootFinder.cpp exRootFinder_SOURCES = exRootFinder.cpp
exRootFinder_CFLAGS = -g -O2 exRootFinder_CXXFLAGS = $(COM_CXXFLAGS)
exRootFinder_LDFLAGS = -L../lib/.libs -lLatAnalyze exRootFinder_LDFLAGS = -L../lib/.libs -lLatAnalyze
ACLOCAL_AMFLAGS = -I .buildutils/m4 ACLOCAL_AMFLAGS = -I .buildutils/m4

View File

@ -1,5 +1,3 @@
#include <iostream>
#include <iomanip>
#include <LatAnalyze/CompiledFunction.hpp> #include <LatAnalyze/CompiledFunction.hpp>
using namespace std; using namespace std;

View File

@ -1,4 +1,3 @@
#include <iostream>
#include <LatAnalyze/Derivative.hpp> #include <LatAnalyze/Derivative.hpp>
#include <LatAnalyze/CompiledFunction.hpp> #include <LatAnalyze/CompiledFunction.hpp>
#include <LatAnalyze/Math.hpp> #include <LatAnalyze/Math.hpp>

View File

@ -1,53 +1,77 @@
#include <iostream> #include <iostream>
#include <cmath> #include <cmath>
#include <LatAnalyze/CompiledModel.hpp> #include <LatAnalyze/CompiledModel.hpp>
#include <LatAnalyze/MinuitMinimizer.hpp> #include <LatAnalyze/Io.hpp>
#include <LatAnalyze/GslMinimizer.hpp>
#include <LatAnalyze/Plot.hpp> #include <LatAnalyze/Plot.hpp>
#include <LatAnalyze/RandGen.hpp>
#include <LatAnalyze/XYStatData.hpp> #include <LatAnalyze/XYStatData.hpp>
using namespace std; using namespace std;
using namespace Latan; using namespace Latan;
const Index nPoint = 20; const Index nPoint1 = 10, nPoint2 = 10;
const double exactPar[2] = {0.5,5.0}, dx = 10.0/static_cast<double>(nPoint); const double xErr = .1, yErr = .3;
const double exactPar[2] = {0.5,5.};
const double dx1 = 10.0/static_cast<double>(nPoint1);
const double dx2 = 5.0/static_cast<double>(nPoint2);
int main(void) int main(void)
{ {
// generate fake data // generate fake data
XYStatData data(nPoint, 1, 1); XYStatData data;
RandGen rg; random_device rd;
double x_k, y_k; mt19937 gen(rd());
DoubleModel f = compile("return p_1*exp(-x_0*p_0);", 1, 2); normal_distribution<> dis;
double xBuf[2];
for (Index k = 0; k < nPoint; ++k) DoubleModel f([](const double *x, const double *p)
{return p[1]*exp(-x[0]*p[0])+x[1];}, 2, 2);
cout << "-- generating fake data..." << endl;
data.addXDim(nPoint1);
data.addXDim(nPoint2);
data.addYDim();
for (Index i1 = 0; i1 < nPoint1; ++i1)
{ {
x_k = k*dx; xBuf[0] = i1*dx1;
y_k = f(&x_k, exactPar) + rg.gaussian(0.0, 0.1); data.x(i1, 0) = xErr*dis(gen) + xBuf[0];
cout << x_k << " " << y_k << " " << 0.1 << endl; for (Index i2 = 0; i2 < nPoint2; ++i2)
data.x(0, k) = x_k; {
data.y(0, k) = y_k; xBuf[1] = i2*dx2;
data.x(i2, 1) = xBuf[1];
data.y(data.dataIndex(i1, i2), 0) = yErr*dis(gen)
+ f(xBuf, exactPar);
}
} }
data.yyVar(0, 0).diagonal() = DMat::Constant(nPoint, 1, 0.1*0.1); data.setXError(0, DVec::Constant(data.getXSize(0), xErr));
data.assumeXExact(0); data.assumeXExact(true, 1);
data.setYError(0, DVec::Constant(data.getYSize(), yErr));
// set minimizers
DVec init = DVec::Constant(2, 0.1);
FitResult p;
GslMinimizer min(GslMinimizer::Algorithm::bfgs2);
// fit // fit
DVec init = DVec::Constant(2, 0.5); min.setVerbosity(Minimizer::Verbosity::Debug);
FitResult p; cout << "-- fit..." << endl;
MinuitMinimizer minimizer; f.parName().setName(0, "m");
f.parName().setName(1, "A");
p = data.fit(min, init, f);
p.print();
data.fitAllPoints(); // plot
p = data.fit(minimizer, init, f); Plot plot;
DVec ref(2);
XYStatData res;
cout << "a= " << p(0) << " b= " << p(1); cout << "-- generating plots..." << endl;
cout << " chi^2/ndof= " << p.getChi2PerDof(); ref(1) = 0.;
cout << " p-value= " << p.getPValue() <<endl; res = data.getPartialResiduals(p, ref, 0);
plot << PlotRange(Axis::x, 0., 10.);
// plot result plot << Color("rgb 'blue'");
Plot plot; plot << PlotFunction(p.getModel().bind(0, ref), 0., 10.);
plot << Color("rgb 'red'");
plot << LogScale(Axis::y) << PlotData(data); plot << PlotData(res);
plot << Color("rgb 'blue'") << PlotFunction(p.getModel(), 0.0, 10.0);
plot.display(); plot.display();
return EXIT_SUCCESS; return EXIT_SUCCESS;

78
examples/exFitSample.cpp Normal file
View File

@ -0,0 +1,78 @@
#include <LatAnalyze/CompiledModel.hpp>
#include <LatAnalyze/GslMinimizer.hpp>
#include <LatAnalyze/Plot.hpp>
#include <LatAnalyze/XYSampleData.hpp>
using namespace std;
using namespace Latan;
const Index nPoint1 = 10, nPoint2 = 10;
const Index nSample = 1000;
const double xErr = .1, yErr = .3;
const double exactPar[2] = {0.5,5.};
const double dx1 = 10.0/static_cast<double>(nPoint1);
const double dx2 = 5.0/static_cast<double>(nPoint2);
int main(void)
{
// generate fake data
XYSampleData data(nSample);
double xBuf[2];
random_device rd;
mt19937 gen(rd());
normal_distribution<> dis;
DoubleModel f([](const double *x, const double *p)
{return p[1]*exp(-x[0]*p[0])+x[1];}, 2, 2);
cout << "-- generating fake data..." << endl;
data.addXDim(nPoint1);
data.addXDim(nPoint2);
data.addYDim();
for (Index s = central; s < nSample; ++s)
{
for (Index i1 = 0; i1 < nPoint1; ++i1)
{
xBuf[0] = i1*dx1;
data.x(i1, 0)[s] = xErr*dis(gen) + xBuf[0];
for (Index i2 = 0; i2 < nPoint2; ++i2)
{
xBuf[1] = i2*dx2;
data.x(i2, 1)[s] = xBuf[1];
data.y(data.dataIndex(i1, i2), 0)[s] = yErr*dis(gen)
+ f(xBuf, exactPar);
}
}
}
data.assumeXExact(true, 1);
// set minimizers
DVec init = DVec::Constant(2, 0.1);
SampleFitResult p;
GslMinimizer min(GslMinimizer::Algorithm::bfgs2);
// fit
cout << "-- fit..." << endl;
f.parName().setName(0, "m");
f.parName().setName(1, "A");
p = data.fit(min, init, f);
p.print();
// plot
Plot plot;
DVec ref(2);
XYStatData res;
cout << "-- generating plots..." << endl;
ref(1) = 0.;
res = data.getPartialResiduals(p, ref, 0).getData();
plot << PlotRange(Axis::x, 0., 10.);
plot << Color("rgb 'blue'");
plot << PlotPredBand(p.getModel(_).bind(0, ref), 0., 10.);
plot << Color("rgb 'blue'");
plot << PlotFunction(p.getModel().bind(0, ref), 0., 10.);
plot << Color("rgb 'red'");
plot << PlotData(res);
plot.display();
return EXIT_SUCCESS;
}

View File

@ -1,4 +1,3 @@
#include <iostream>
#include <LatAnalyze/CompiledFunction.hpp> #include <LatAnalyze/CompiledFunction.hpp>
#include <LatAnalyze/GslQagsIntegrator.hpp> #include <LatAnalyze/GslQagsIntegrator.hpp>

View File

@ -1,22 +1,3 @@
/*
* TabFunction.cpp, part of LatAnalyze 3
*
* Copyright (C) 2013 - 2015 Antonin Portelli, Matt Spraggs
*
* LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LatAnalyze 3 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
*/
#include <LatAnalyze/TabFunction.hpp> #include <LatAnalyze/TabFunction.hpp>
int main(void) int main(void)

View File

@ -1,4 +1,3 @@
#include <iostream>
#include <LatAnalyze/Io.hpp> #include <LatAnalyze/Io.hpp>
#include <LatAnalyze/Mat.hpp> #include <LatAnalyze/Mat.hpp>
#include <LatAnalyze/Math.hpp> #include <LatAnalyze/Math.hpp>
@ -9,7 +8,7 @@ using namespace Latan;
int main(void) int main(void)
{ {
DMat A(2, 3), B(3, 2), C = DMat::Random(6, 6); DMat A(2, 3), B(3, 2), C = DMat::Random(6, 6);
const string fileName = "exMat.h5"; const string fileName = "exMat.dat";
A << 1, 2, 3, A << 1, 2, 3,
4, 5, 6; 4, 5, 6;

View File

@ -1,4 +1,3 @@
#include <iostream>
#include <LatAnalyze/Math.hpp> #include <LatAnalyze/Math.hpp>
#include <LatAnalyze/MathInterpreter.hpp> #include <LatAnalyze/MathInterpreter.hpp>

View File

@ -1,6 +1,5 @@
#include <iostream>
#include <LatAnalyze/CompiledFunction.hpp> #include <LatAnalyze/CompiledFunction.hpp>
#include <LatAnalyze/MinuitMinimizer.hpp> #include <LatAnalyze/GslMinimizer.hpp>
using namespace std; using namespace std;
using namespace Latan; using namespace Latan;
@ -17,8 +16,8 @@ int main(int argc, char* argv[])
} }
source = argv[1]; source = argv[1];
DoubleFunction f = compile(source, 1); DoubleFunction f = compile(source, 1);
MinuitMinimizer minimize; GslMinimizer minimize;
DVec init(1); DVec init(1);
double min; double min;

View File

@ -1,4 +1,3 @@
#include <iostream>
#include <LatAnalyze/CompiledFunction.hpp> #include <LatAnalyze/CompiledFunction.hpp>
#include <LatAnalyze/Math.hpp> #include <LatAnalyze/Math.hpp>
#include <LatAnalyze/Plot.hpp> #include <LatAnalyze/Plot.hpp>

View File

@ -1,53 +1,26 @@
#include <iostream>
#include <LatAnalyze/Io.hpp> #include <LatAnalyze/Io.hpp>
#include <LatAnalyze/CompiledFunction.hpp> #include <LatAnalyze/CompiledFunction.hpp>
#include <LatAnalyze/Plot.hpp> #include <LatAnalyze/Plot.hpp>
#include <LatAnalyze/RandGen.hpp>
using namespace std; using namespace std;
using namespace Latan; using namespace Latan;
constexpr int seqLength = 25;
constexpr int saveStep = 9;
constexpr Index nDraw = 20000; constexpr Index nDraw = 20000;
const string stateFileName = "exRand.seed"; const string stateFileName = "exRand.seed";
int main(void) int main(void)
{ {
RandGenState state; random_device rd;
RandGen gen[2]; mt19937 gen(rd());
AsciiFile stateFile(stateFileName, File::Mode::write|File::Mode::read); normal_distribution<> dis;
DVec gauss(nDraw); DVec gauss(nDraw);
Plot p; Plot p;
Histogram h; Histogram h;
cout << "- GENERATOR STATE I/O TESTS" << endl;
cout << "-- generating a " << seqLength << " steps random sequence..."
<< endl;
for (int i = 0; i < seqLength; ++i)
{
if (i == saveStep)
{
state = gen[0].getState();
stateFile.save(state, "exRand");
cout << "generator state after step " << saveStep - 1
<< " saved in '" << stateFileName << "'" << endl;
}
cout << "step " << i << "\t: " << gen[0].uniform() <<endl;
}
cout << "-- setting up another generator from '" << stateFileName << "'..."
<< endl;
gen[1].setState(stateFile.read<RandGenState>("exRand"));
cout << "-- generating a " << seqLength << " steps random sequence..."
<< endl;
for (int i = 0; i < seqLength; ++i)
{
cout << "step " << i << "\t: " << gen[1].uniform() <<endl;
}
cout << "-- generating " << nDraw << " Gaussian random numbers..." << endl; cout << "-- generating " << nDraw << " Gaussian random numbers..." << endl;
FOR_VEC(gauss, i) FOR_VEC(gauss, i)
{ {
gauss(i) = gen[0].gaussian(); gauss(i) = dis(gen);
} }
h.setFromData(gauss, -5., 5., 40); h.setFromData(gauss, -5., 5., 40);
h.normalize(); h.normalize();

View File

@ -1,4 +1,3 @@
#include <iostream>
#include <LatAnalyze/Function.hpp> #include <LatAnalyze/Function.hpp>
#include <LatAnalyze/GslHybridRootFinder.hpp> #include <LatAnalyze/GslHybridRootFinder.hpp>

View File

@ -1,7 +1,7 @@
/* /*
* AsciiFile.cpp, part of LatAnalyze 3 * AsciiFile.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -71,7 +71,22 @@ void AsciiFile::save(const DMat &m, const std::string &name)
fileStream_.precision(defaultPrec); fileStream_.precision(defaultPrec);
} }
void AsciiFile::save(const DMatSample &s, const std::string &name) void AsciiFile::save(const DSample &ds, const std::string &name)
{
if (name.empty())
{
LATAN_ERROR(Io, "trying to save data with an empty name");
}
checkWritability();
isParsed_ = false;
fileStream_ << "#L latan_begin rs_sample " << name << endl;
fileStream_ << ds.size() << endl;
save(ds.matrix(), name + "_data");
fileStream_ << "#L latan_end rs_sample " << endl;
}
void AsciiFile::save(const DMatSample &ms, const std::string &name)
{ {
if (name.empty()) if (name.empty())
{ {
@ -81,29 +96,15 @@ void AsciiFile::save(const DMatSample &s, const std::string &name)
checkWritability(); checkWritability();
isParsed_ = false; isParsed_ = false;
fileStream_ << "#L latan_begin rs_sample " << name << endl; fileStream_ << "#L latan_begin rs_sample " << name << endl;
fileStream_ << s.size() << endl; fileStream_ << ms.size() << endl;
save(s[central], name + "_C"); save(ms[central], name + "_C");
for (Index i = 0; i < s.size(); ++i) for (Index i = 0; i < ms.size(); ++i)
{ {
save(s[i], name + "_S_" + strFrom(i)); save(ms[i], name + "_S_" + strFrom(i));
} }
fileStream_ << "#L latan_end rs_sample " << endl; fileStream_ << "#L latan_end rs_sample " << endl;
} }
void AsciiFile::save(const RandGenState &state, const std::string &name)
{
if (name.empty())
{
LATAN_ERROR(Io, "trying to save data with an empty name");
}
checkWritability();
isParsed_ = false;
fileStream_ << "#L latan_begin rg_state " << name << endl;
fileStream_ << state << endl;
fileStream_ << "#L latan_end rg_state " << endl;
}
// read first name //////////////////////////////////////////////////////////// // read first name ////////////////////////////////////////////////////////////
string AsciiFile::getFirstName(void) string AsciiFile::getFirstName(void)
{ {

View File

@ -1,7 +1,7 @@
/* /*
* AsciiFile.hpp, part of LatAnalyze 3 * AsciiFile.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -25,8 +25,6 @@
#include <LatAnalyze/Mat.hpp> #include <LatAnalyze/Mat.hpp>
#include <LatAnalyze/MatSample.hpp> #include <LatAnalyze/MatSample.hpp>
#include <LatAnalyze/ParserState.hpp> #include <LatAnalyze/ParserState.hpp>
#include <LatAnalyze/RandGen.hpp>
#include <fstream>
BEGIN_LATAN_NAMESPACE BEGIN_LATAN_NAMESPACE
@ -48,11 +46,11 @@ public:
bool isFirst; bool isFirst;
std::string first; std::string first;
// parsing buffers // parsing buffers
RandGenState stateBuf; int intBuf;
DSample dSampleBuf;
DMatSample dMatSampleBuf; DMatSample dMatSampleBuf;
std::queue<DMat> dMatQueue; std::queue<DMat> dMatQueue;
std::queue<double> doubleQueue; std::queue<double> doubleQueue;
std::queue<int> intQueue;
private: private:
// allocation/deallocation functions defined in IoAsciiLexer.lpp // allocation/deallocation functions defined in IoAsciiLexer.lpp
virtual void initScanner(void); virtual void initScanner(void);
@ -66,8 +64,8 @@ public:
virtual ~AsciiFile(void); virtual ~AsciiFile(void);
// access // access
virtual void save(const DMat &m, const std::string &name); virtual void save(const DMat &m, const std::string &name);
virtual void save(const DMatSample &s, const std::string &name); virtual void save(const DSample &ds, const std::string &name);
virtual void save(const RandGenState &state, const std::string &name); virtual void save(const DMatSample &ms, const std::string &name);
// read first name // read first name
virtual std::string getFirstName(void); virtual std::string getFirstName(void);
// tests // tests

View File

@ -1,7 +1,7 @@
/* /*
* AsciiLexer.lpp, part of LatAnalyze 3 * AsciiLexer.lpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -25,20 +25,9 @@
%option yylineno %option yylineno
%{ %{
#include <iostream>
#include <LatAnalyze/AsciiFile.hpp> #include <LatAnalyze/AsciiFile.hpp>
#include "AsciiParser.hpp" #include "AsciiParser.hpp"
#if (defined __INTEL_COMPILER)
#pragma warning disable 1682 2259
#elif (defined __GNUC__)||(defined __clang__)
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
using namespace std; using namespace std;
using namespace Latan; using namespace Latan;
@ -76,7 +65,7 @@ BLANK [ \t]
%% %%
{LMARK} {BEGIN(MARK);} {LMARK} {BEGIN(MARK);}
{INT} {yylval->val_int = strTo<int>(yytext); RETTOK(INT);} {INT} {yylval->val_int = strTo<long int>(yytext); RETTOK(INT);}
{FLOAT} {yylval->val_double = strTo<double>(yytext); RETTOK(FLOAT);} {FLOAT} {yylval->val_double = strTo<double>(yytext); RETTOK(FLOAT);}
({ALPHA}|{DIGIT})+ {strcpy(yylval->val_str,yytext); RETTOK(ID);} ({ALPHA}|{DIGIT})+ {strcpy(yylval->val_str,yytext); RETTOK(ID);}
<MARK>latan_begin {BEGIN(TYPE); RETTOK(OPEN);} <MARK>latan_begin {BEGIN(TYPE); RETTOK(OPEN);}

View File

@ -1,7 +1,7 @@
/* /*
* AsciiParser.ypp, part of LatAnalyze 3 * AsciiParser.ypp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -22,18 +22,6 @@
#include <LatAnalyze/AsciiFile.hpp> #include <LatAnalyze/AsciiFile.hpp>
#include <LatAnalyze/Mat.hpp> #include <LatAnalyze/Mat.hpp>
#include <LatAnalyze/MatSample.hpp> #include <LatAnalyze/MatSample.hpp>
#include <LatAnalyze/RandGen.hpp>
#include <iostream>
#include <sstream>
#include <utility>
#include <cstring>
#if (defined __INTEL_COMPILER)
#pragma warning disable 1682 2259
#elif (defined __GNUC__)||(defined __clang__)
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
using namespace std; using namespace std;
using namespace Latan; using namespace Latan;
@ -47,7 +35,7 @@
%} %}
%pure-parser %pure-parser
%name-prefix = "_Ascii_" %name-prefix "_Ascii_"
%locations %locations
%defines %defines
%error-verbose %error-verbose
@ -57,10 +45,10 @@
%union %union
{ {
int val_int; long int val_int;
double val_double; double val_double;
char val_char; char val_char;
char val_str[256]; char val_str[256];
} }
%token <val_char> ERR %token <val_char> ERR
@ -69,7 +57,7 @@
%token <val_str> ID %token <val_str> ID
%token OPEN CLOSE MAT SAMPLE RG_STATE %token OPEN CLOSE MAT SAMPLE RG_STATE
%type <val_str> mat sample rg_state %type <val_str> mat matsample dsample
%{ %{
int _Ascii_lex(YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner); int _Ascii_lex(YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner);
@ -101,16 +89,16 @@ data:
(*state->data)[$1].reset(new DMat(state->dMatQueue.front())); (*state->data)[$1].reset(new DMat(state->dMatQueue.front()));
state->dMatQueue.pop(); state->dMatQueue.pop();
} }
| sample | dsample
{
TEST_FIRST($1);
(*state->data)[$1].reset(new DSample(state->dSampleBuf));
}
| matsample
{ {
TEST_FIRST($1); TEST_FIRST($1);
(*state->data)[$1].reset(new DMatSample(state->dMatSampleBuf)); (*state->data)[$1].reset(new DMatSample(state->dMatSampleBuf));
} }
| rg_state
{
TEST_FIRST($1);
(*state->data)[$1].reset(new RandGenState(state->stateBuf));
}
; ;
mat: mat:
@ -138,15 +126,37 @@ mat:
} }
; ;
sample: dsample:
OPEN SAMPLE ID INT mats CLOSE SAMPLE OPEN SAMPLE ID INT mat CLOSE SAMPLE
{
const unsigned int nSample = $4, os = DMatSample::offset;
DMat &m = state->dMatQueue.front();
if (m.rows() != nSample + os)
{
LATAN_ERROR(Size, "double sample '" + *state->streamName + ":"
+ $3 + "' has a wrong size");
}
if (m.cols() != 1)
{
LATAN_ERROR(Size, "double sample '" + *state->streamName + ":"
+ $3 + "' is not stored as a column vector");
}
state->dSampleBuf = m.array();
state->dMatQueue.pop();
strcpy($$, $3);
}
;
matsample:
OPEN SAMPLE ID INT mat mats CLOSE SAMPLE
{ {
const unsigned int nSample = $4, os = DMatSample::offset; const unsigned int nSample = $4, os = DMatSample::offset;
if (state->dMatQueue.size() != nSample + os) if (state->dMatQueue.size() != nSample + os)
{ {
LATAN_ERROR(Size, "sample '" + *state->streamName + ":" + $3 + LATAN_ERROR(Size, "matrix sample '" + *state->streamName + ":"
"' has a wrong size"); + $3 + "' has a wrong size");
} }
state->dMatSampleBuf.resize(nSample); state->dMatSampleBuf.resize(nSample);
state->dMatSampleBuf[central] = state->dMatQueue.front(); state->dMatSampleBuf[central] = state->dMatQueue.front();
@ -158,22 +168,6 @@ sample:
} }
strcpy($$, $3); strcpy($$, $3);
} }
rg_state:
OPEN RG_STATE ID ints CLOSE RG_STATE
{
if (state->intQueue.size() != RLXG_STATE_SIZE)
{
LATAN_ERROR(Size, "random generator state '" + *state->streamName
+ ":" + $3 + "' has a wrong size");
}
for (Index i = 0; i < RLXG_STATE_SIZE; ++i)
{
state->stateBuf[i] = state->intQueue.front();
state->intQueue.pop();
}
strcpy($$, $3);
}
; ;
mats: mats:
@ -187,8 +181,3 @@ floats:
| FLOAT {state->doubleQueue.push($1);} | FLOAT {state->doubleQueue.push($1);}
| INT {state->doubleQueue.push(static_cast<double>($1));} | INT {state->doubleQueue.push(static_cast<double>($1));}
; ;
ints:
ints INT {state->intQueue.push($2);}
| INT {state->intQueue.push($1);}
;

View File

@ -1,325 +0,0 @@
/*
* Chi2Function.cpp, part of LatAnalyze 3
*
* Copyright (C) 2013 - 2015 Antonin Portelli
*
* LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LatAnalyze 3 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
*/
#include <LatAnalyze/Chi2Function.hpp>
#include <LatAnalyze/includes.hpp>
#include <LatAnalyze/XYStatData.hpp>
using namespace std;
using namespace Latan;
/******************************************************************************
* Chi2Function implementation *
******************************************************************************/
// constructors ////////////////////////////////////////////////////////////////
Chi2Function::Chi2Function(const XYStatData &data)
: data_(&data)
, buffer_(new Chi2FunctionBuffer)
{
resizeBuffer();
}
Chi2Function::Chi2Function(const XYStatData &data,
const vector<const DoubleModel *> &modelVector)
: Chi2Function(data)
{
setModel(modelVector);
}
// access //////////////////////////////////////////////////////////////////////
Index Chi2Function::getNArg(void) const
{
if (nPar_ < 0)
{
LATAN_ERROR(Memory, "no model set");
}
return nPar_ + data_->getStatXDim()*data_->getNFitPoint();
}
Index Chi2Function::getNDof(void) const
{
if (nPar_ < 0)
{
LATAN_ERROR(Memory, "no model set");
}
return data_->getYDim()*data_->getNFitPoint() - nPar_;
}
Index Chi2Function::getNPar(void) const
{
if (nPar_ < 0)
{
LATAN_ERROR(Memory, "no model set");
}
return nPar_;
}
void Chi2Function::setModel(const DoubleModel &model, const Index j)
{
typedef decltype(model_.size()) size_type;
if (static_cast<Index>(model_.size()) != data_->getYDim())
{
model_.resize(static_cast<size_type>(data_->getYDim()));
}
if (model.getNArg() != data_->getXDim())
{
LATAN_ERROR(Size, "model number of arguments and x-dimension mismatch");
}
for (unsigned int l = 0; l < data_->getYDim(); ++l)
{
if (model_[l]&&(l != j))
{
if (model_[l]->getNPar() != model.getNPar())
{
LATAN_ERROR(Size, "model number of parameter mismatch");
}
}
}
model_[static_cast<size_type>(j)] = &model;
nPar_ = model.getNPar();
}
void Chi2Function::setModel(const vector<const DoubleModel *> &modelVector)
{
typedef decltype(model_.size()) size_type;
if (static_cast<Index>(model_.size()) != data_->getYDim())
{
model_.resize(static_cast<size_type>(data_->getYDim()));
}
if (modelVector.size() != static_cast<size_type>(data_->getYDim()))
{
LATAN_ERROR(Size, "number of models and y-dimension mismatch");
}
for (unsigned int j = 0; j < model_.size(); ++j)
{
if (!modelVector[j])
{
LATAN_ERROR(Memory, "trying to set a null model");
}
if (modelVector[j]->getNArg() != data_->getXDim())
{
LATAN_ERROR(Size, "model number of arguments and x-dimension mismatch");
}
model_[static_cast<size_type>(j)] = modelVector[j];
if (modelVector[j]->getNPar() != modelVector[0]->getNPar())
{
LATAN_ERROR(Size, "model number of parameter mismatch");
}
}
nPar_ = modelVector[0]->getNPar();
}
void Chi2Function::requestInit(void) const
{
buffer_->isInit = false;
}
void Chi2Function::resizeBuffer(void) const
{
Index size;
size = (data_->getYDim() + data_->getStatXDim())*data_->getNFitPoint();
buffer_->v.setConstant(size, 0.0);
buffer_->x.setConstant(data_->getXDim(), 0.0);
buffer_->invVar.setConstant(size, size, 0.0);
buffer_->xInd.setConstant(data_->getStatXDim(), 0);
buffer_->dInd.setConstant(data_->getNFitPoint(), 0);
}
// compute variance matrix inverse /////////////////////////////////////////////
void Chi2Function::setVarianceBlock(const Index l1, const Index l2,
ConstBlock<MatBase<double>> m) const
{
const Index nPoint = data_->getNFitPoint();
FOR_VEC(buffer_->dInd, k2)
FOR_VEC(buffer_->dInd, k1)
{
if (data_->isDataCorrelated(buffer_->dInd(k1), buffer_->dInd(k2)))
{
buffer_->invVar(l1*nPoint + k1, l2*nPoint + k2) =
m(buffer_->dInd(k1), buffer_->dInd(k2));
}
}
}
void Chi2Function::initBuffer(void) const
{
const Index xDim = data_->getXDim();
const Index statXDim = data_->getStatXDim();
const Index yDim = data_->getYDim();
const Index nData = data_->getNData();
const Index nPoint = data_->getNFitPoint();
Index is, kf;
// resize buffer
resizeBuffer();
// build index tables
is = 0;
for (Index i = 0; i < xDim; ++i)
{
if (!data_->isXExact(i))
{
buffer_->xInd(is) = i;
is++;
}
}
kf = 0;
for (Index k = 0; k < nData; ++k)
{
if (data_->isFitPoint(k))
{
buffer_->dInd(kf) = k;
kf++;
}
}
// set y/y variance matrix
for (Index j2 = 0; j2 < yDim; ++j2)
for (Index j1 = 0; j1 < yDim; ++j1)
{
if (data_->isYYCorrelated(j1, j2))
{
setVarianceBlock(j1, j2, data_->yyVar(j1, j2));
}
}
// set x/x variance matrix
FOR_VEC(buffer_->xInd, i2)
FOR_VEC(buffer_->xInd, i1)
{
if (data_->isXXCorrelated(buffer_->xInd(i1), buffer_->xInd(i2)))
{
setVarianceBlock(i1 + yDim, i2 + yDim,
data_->xxVar(buffer_->xInd(i1), buffer_->xInd(i2)));
}
}
// set y/x variance matrix
FOR_VEC(buffer_->xInd, i)
for (Index j = 0; j < yDim; ++j)
{
if (data_->isYXCorrelated(j, buffer_->xInd(i)))
{
setVarianceBlock(j, i + yDim, data_->yxVar(j, buffer_->xInd(i)));
}
}
auto lowerYX = buffer_->invVar.block(yDim*nPoint, 0, yDim*statXDim,
yDim*nPoint);
auto upperYX = buffer_->invVar.block(0, yDim*nPoint, yDim*nPoint,
yDim*statXDim);
lowerYX = upperYX.transpose();
// inversion
buffer_->invVar = buffer_->invVar.pInverse(data_->getSvdTolerance());
buffer_->isInit = true;
}
// function call ///////////////////////////////////////////////////////////////
double Chi2Function::operator()(const double *arg) const
{
typedef decltype(model_.size()) size_type;
if (!model_[0])
{
LATAN_ERROR(Memory, "null model");
}
const Index xDim = data_->getXDim();
const Index yDim = data_->getYDim();
const Index nPoint = data_->getNFitPoint();
Index is;
ConstMap<DVec> xi(arg + nPar_, getNArg() - nPar_, 1);
double res;
// initialize buffers if necessary
if (!buffer_->isInit)
{
initBuffer();
}
// set the upper part of v: f_j(xi, p) - y_j
for (Index j = 0; j < yDim; ++j)
FOR_VEC(buffer_->dInd, k)
{
const DoubleModel *f = model_[static_cast<size_type>(j)];
double f_jk, y_jk = data_->y(j, buffer_->dInd(k));
if (!f)
{
LATAN_ERROR(Memory, "null model");
}
is = 0;
for (Index i = 0; i < xDim; ++i)
{
if (data_->isXExact(i))
{
buffer_->x(i) = data_->x(i, buffer_->dInd(k));
}
else
{
buffer_->x(i) = xi(is*nPoint + k);
is++;
}
}
// call model on double pointers to avoid any copy
f_jk = (*f)(buffer_->x.data(), arg);
buffer_->v(j*nPoint + k) = f_jk - y_jk;
}
// set the down part of v: xi_ik - x_ik
FOR_VEC(buffer_->xInd, i)
FOR_VEC(buffer_->dInd, k)
{
double x_ik = data_->x(buffer_->xInd(i), buffer_->dInd(k));
double xi_ik = xi(i*nPoint + k);
buffer_->v(yDim*nPoint + i*nPoint + k) = xi_ik - x_ik;
}
// compute result
res = buffer_->v.dot(buffer_->invVar*buffer_->v);
return res;
}
// DoubleFunction factory //////////////////////////////////////////////////////
DoubleFunction Chi2Function::makeFunction(const bool makeHardCopy) const
{
DoubleFunction res;
if (makeHardCopy)
{
Chi2Function copy(*this);
res.setFunction([copy](const double *p){return copy(p);}, getNArg());
}
else
{
res.setFunction([this](const double *p){return (*this)(p);}, getNArg());
}
return res;
}

View File

@ -1,80 +0,0 @@
/*
* Chi2Function.hpp, part of LatAnalyze 3
*
* Copyright (C) 2013 - 2015 Antonin Portelli
*
* LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LatAnalyze 3 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Latan_Chi2Function_hpp_
#define Latan_Chi2Function_hpp_
#include <LatAnalyze/Global.hpp>
#include <LatAnalyze/Function.hpp>
#include <LatAnalyze/Model.hpp>
BEGIN_LATAN_NAMESPACE
/******************************************************************************
* <Class> *
******************************************************************************/
// forward declaration of XYStatData
class XYStatData;
class Chi2Function: public DoubleFunctionFactory
{
private:
struct Chi2FunctionBuffer
{
DVec v, x;
DMat invVar;
bool isInit{false};
Vec<Index> xInd, dInd;
};
public:
// constructor
explicit Chi2Function(const XYStatData &data);
Chi2Function(const XYStatData &data,
const std::vector<const DoubleModel *> &modelVector);
// destructor
virtual ~Chi2Function(void) = default;
// access
virtual Index getNArg(void) const;
Index getNDof(void) const;
Index getNPar(void) const;
void setModel(const DoubleModel &model, const Index j = 0);
void setModel(const std::vector<const DoubleModel *> &modelVector);
void requestInit(void) const;
// function call
double operator()(const double *arg) const;
// factory
virtual DoubleFunction makeFunction(const bool makeHardCopy = true) const;
private:
// access
void resizeBuffer(void) const;
// compute variance matrix inverse
void setVarianceBlock(const Index l1, const Index l2,
ConstBlock<MatBase<double>> m) const;
void initBuffer(void) const;
private:
const XYStatData *data_;
std::shared_ptr<Chi2FunctionBuffer> buffer_;
std::vector<const DoubleModel *> model_;
Index nPar_{-1};
};
END_LATAN_NAMESPACE
#endif // Latan_Chi2Function_hpp_

View File

@ -1,7 +1,7 @@
/* /*
* CompiledFunction.cpp, part of LatAnalyze 3 * CompiledFunction.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
* CompiledFunction.hpp, part of LatAnalyze 3 * CompiledFunction.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
* CompiledModel.cpp, part of LatAnalyze 3 * CompiledModel.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
* CompiledModel.hpp, part of LatAnalyze 3 * CompiledModel.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
* Dataset.hpp, part of LatAnalyze 3 * Dataset.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -23,9 +23,6 @@
#include <LatAnalyze/Global.hpp> #include <LatAnalyze/Global.hpp>
#include <LatAnalyze/File.hpp> #include <LatAnalyze/File.hpp>
#include <LatAnalyze/StatArray.hpp> #include <LatAnalyze/StatArray.hpp>
#include <LatAnalyze/RandGen.hpp>
#include <fstream>
#include <vector>
BEGIN_LATAN_NAMESPACE BEGIN_LATAN_NAMESPACE
@ -35,6 +32,8 @@ BEGIN_LATAN_NAMESPACE
template <typename T> template <typename T>
class Dataset: public StatArray<T> class Dataset: public StatArray<T>
{ {
public:
typedef std::random_device::result_type SeedType;
public: public:
// constructors // constructors
Dataset(void) = default; Dataset(void) = default;
@ -46,7 +45,8 @@ public:
template <typename FileType> template <typename FileType>
void load(const std::string &listFileName, const std::string &dataName); void load(const std::string &listFileName, const std::string &dataName);
// resampling // resampling
Sample<T> bootstrapMean(const Index nSample, RandGen& generator); Sample<T> bootstrapMean(const Index nSample, const SeedType seed);
Sample<T> bootstrapMean(const Index nSample);
private: private:
// mean from pointer vector for resampling // mean from pointer vector for resampling
void ptVectorMean(T &m, const std::vector<const T *> &v); void ptVectorMean(T &m, const std::vector<const T *> &v);
@ -82,26 +82,23 @@ void Dataset<T>::load(const std::string &listFileName,
// resampling ////////////////////////////////////////////////////////////////// // resampling //////////////////////////////////////////////////////////////////
template <typename T> template <typename T>
Sample<T> Dataset<T>::bootstrapMean(const Index nSample, RandGen& generator) Sample<T> Dataset<T>::bootstrapMean(const Index nSample, const SeedType seed)
{ {
typedef typename std::vector<const T *>::size_type size_type; std::vector<const T *> data(this->size());
Sample<T> s(nSample);
size_type nData = static_cast<size_type>(this->size()); std::mt19937 gen(seed);
std::vector<const T *> data(nData); std::uniform_int_distribution<Index> dis(0, this->size() - 1);
Sample<T> s(nSample);
for (size_type j = 0; j < nData; ++j) for (unsigned int j = 0; j < this->size(); ++j)
{ {
data[j] = &((*this)[static_cast<Index>(j)]); data[j] = &((*this)[static_cast<Index>(j)]);
} }
ptVectorMean(s[central], data); ptVectorMean(s[central], data);
for (Index i = 0; i < nSample; ++i) for (Index i = 0; i < nSample; ++i)
{ {
for (size_type j = 0; j < nData; ++j) for (unsigned int j = 0; j < this->size(); ++j)
{ {
Index k= static_cast<Index>(generator.discreteUniform(static_cast<unsigned int>(nData))); data[j] = &((*this)[dis(gen)]);
data[j] = &((*this)[k]);
} }
ptVectorMean(s[i], data); ptVectorMean(s[i], data);
} }
@ -109,6 +106,14 @@ Sample<T> Dataset<T>::bootstrapMean(const Index nSample, RandGen& generator)
return s; return s;
} }
template <typename T>
Sample<T> Dataset<T>::bootstrapMean(const Index nSample)
{
std::random_device rd;
return bootstrapMean(nSample, rd());
}
template <typename T> template <typename T>
void Dataset<T>::ptVectorMean(T &m, const std::vector<const T *> &v) void Dataset<T>::ptVectorMean(T &m, const std::vector<const T *> &v)
{ {

View File

@ -1,7 +1,7 @@
/* /*
* Derivative.cpp, part of LatAnalyze 3 * Derivative.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -31,11 +31,12 @@ using namespace Math;
// constructor ///////////////////////////////////////////////////////////////// // constructor /////////////////////////////////////////////////////////////////
Derivative::Derivative(const DoubleFunction &f, const Index dir, Derivative::Derivative(const DoubleFunction &f, const Index dir,
const double step) const double step)
: f_(f) : buffer_(new DVec(f.getNArg()))
, dir_(dir) {
, step_(step) setFunction(f);
, buffer_(new DVec(f.getNArg())) setDir(dir);
{} setStep(step);
}
Derivative::Derivative(const DoubleFunction &f, const Index dir, Derivative::Derivative(const DoubleFunction &f, const Index dir,
const Index order, const DVec &point, const double step) const Index order, const DVec &point, const double step)
@ -45,6 +46,11 @@ Derivative::Derivative(const DoubleFunction &f, const Index dir,
} }
// access ////////////////////////////////////////////////////////////////////// // access //////////////////////////////////////////////////////////////////////
Index Derivative::getDir(void) const
{
return dir_;
}
Index Derivative::getOrder(void) const Index Derivative::getOrder(void) const
{ {
return order_; return order_;
@ -60,6 +66,11 @@ double Derivative::getStep(void) const
return step_; return step_;
} }
void Derivative::setDir(const Index dir)
{
dir_ = dir;
}
void Derivative::setFunction(const DoubleFunction &f) void Derivative::setFunction(const DoubleFunction &f)
{ {
f_ = f; f_ = f;

View File

@ -1,7 +1,7 @@
/* /*
* Derivative.hpp, part of LatAnalyze 3 * Derivative.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -39,9 +39,11 @@ public:
// destructor // destructor
virtual ~Derivative(void) = default; virtual ~Derivative(void) = default;
// access // access
Index getDir(void) const;
Index getNPoint(void) const; Index getNPoint(void) const;
Index getOrder(void) const; Index getOrder(void) const;
double getStep(void) const; double getStep(void) const;
void setDir(const Index dir);
void setFunction(const DoubleFunction &f); void setFunction(const DoubleFunction &f);
void setOrderAndPoint(const Index order, const DVec &point); void setOrderAndPoint(const Index order, const DVec &point);
void setStep(const double step); void setStep(const double step);
@ -73,16 +75,13 @@ public:
static const Index defaultPrecOrder = 2; static const Index defaultPrecOrder = 2;
public: public:
// constructor // constructor
CentralDerivative(const DoubleFunction &f, const Index dir = 0, CentralDerivative(const DoubleFunction &f = DoubleFunction(),
const Index dir = 0,
const Index order = 1, const Index order = 1,
const Index precOrder = defaultPrecOrder); const Index precOrder = defaultPrecOrder);
// destructor // destructor
virtual ~CentralDerivative(void) = default; virtual ~CentralDerivative(void) = default;
// access // access
using Derivative::getNPoint;
using Derivative::getStep;
using Derivative::getOrder;
using Derivative::setStep;
Index getPrecOrder(void) const; Index getPrecOrder(void) const;
void setOrder(const Index order, const Index precOrder = defaultPrecOrder); void setOrder(const Index order, const Index precOrder = defaultPrecOrder);
// function call // function call

View File

@ -1,7 +1,7 @@
/* /*
* Exceptions.cpp, part of LatAnalyze 3 * Exceptions.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -41,6 +41,7 @@ CONST_EXC(Range, Logic("range error: " + msg, loc))
CONST_EXC(Size, Logic("size error: " + msg, loc)) CONST_EXC(Size, Logic("size error: " + msg, loc))
// runtime errors // runtime errors
CONST_EXC(Runtime, runtime_error(Env::msgPrefix + msg + ERR_SUFF)) CONST_EXC(Runtime, runtime_error(Env::msgPrefix + msg + ERR_SUFF))
CONST_EXC(Argument, Runtime("argument error: " + msg, loc))
CONST_EXC(Compilation, Runtime("compilation error: " + msg, loc)) CONST_EXC(Compilation, Runtime("compilation error: " + msg, loc))
CONST_EXC(Io, Runtime("IO error: " + msg, loc)) CONST_EXC(Io, Runtime("IO error: " + msg, loc))
CONST_EXC(Memory, Runtime("memory error: " + msg, loc)) CONST_EXC(Memory, Runtime("memory error: " + msg, loc))

View File

@ -1,7 +1,7 @@
/* /*
* Exceptions.hpp, part of LatAnalyze 3 * Exceptions.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -51,6 +51,7 @@ namespace Exceptions
DECL_EXC(Size, Logic); DECL_EXC(Size, Logic);
// runtime errors // runtime errors
DECL_EXC(Runtime, std::runtime_error); DECL_EXC(Runtime, std::runtime_error);
DECL_EXC(Argument, Runtime);
DECL_EXC(Compilation, Runtime); DECL_EXC(Compilation, Runtime);
DECL_EXC(Io, Runtime); DECL_EXC(Io, Runtime);
DECL_EXC(Memory, Runtime); DECL_EXC(Memory, Runtime);

View File

@ -1,7 +1,7 @@
/* /*
* File.cpp, part of LatAnalyze 3 * File.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -52,10 +52,6 @@ unsigned int File::getMode(void) const
// internal functions ////////////////////////////////////////////////////////// // internal functions //////////////////////////////////////////////////////////
void File::deleteData(void) void File::deleteData(void)
{ {
for (auto &i : data_)
{
i.second.reset();
}
data_.clear(); data_.clear();
} }

View File

@ -1,7 +1,7 @@
/* /*
* File.hpp, part of LatAnalyze 3 * File.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -24,9 +24,6 @@
#include <LatAnalyze/IoObject.hpp> #include <LatAnalyze/IoObject.hpp>
#include <LatAnalyze/Mat.hpp> #include <LatAnalyze/Mat.hpp>
#include <LatAnalyze/MatSample.hpp> #include <LatAnalyze/MatSample.hpp>
#include <LatAnalyze/RandGen.hpp>
#include <queue>
#include <unordered_map>
BEGIN_LATAN_NAMESPACE BEGIN_LATAN_NAMESPACE
@ -61,8 +58,8 @@ public:
template <typename IoT> template <typename IoT>
const IoT & read(const std::string &name = ""); const IoT & read(const std::string &name = "");
virtual void save(const DMat &m, const std::string &name) = 0; virtual void save(const DMat &m, const std::string &name) = 0;
virtual void save(const DMatSample &state, const std::string &name) = 0; virtual void save(const DSample &ds, const std::string &name) = 0;
virtual void save(const RandGenState &state, const std::string &name) = 0; virtual void save(const DMatSample &ms, const std::string &name) = 0;
// read first name // read first name
virtual std::string getFirstName(void) = 0; virtual std::string getFirstName(void) = 0;
// tests // tests

View File

@ -1,7 +1,7 @@
/* /*
* FitInterface.cpp, part of LatAnalyze 3 * FitInterface.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -24,186 +24,770 @@ using namespace std;
using namespace Latan; using namespace Latan;
/****************************************************************************** /******************************************************************************
* FitInterface implementation * * FitInterface implementation *
******************************************************************************/ ******************************************************************************/
// constructors //////////////////////////////////////////////////////////////// // constructor /////////////////////////////////////////////////////////////////
FitInterface::FitInterface(const Index nData, const Index xDim, FitInterface::FitInterface(void)
const Index yDim) : xName_("x")
, yName_("y")
{}
// copy object (not as a constructor to be accessed from derived class) ////////
void FitInterface::copyInterface(const FitInterface &d)
{ {
resize(nData, xDim, yDim); *this = d;
scheduleFitVarMatInit();
} }
// access ////////////////////////////////////////////////////////////////////// // add dimensions //////////////////////////////////////////////////////////////
void FitInterface::assumeXExact(const Index i, const bool isExact) void FitInterface::addXDim(const Index nData, const string name,
const bool isExact)
{ {
isXExact_(i) = (isExact) ? 1 : 0; if (getYSize() != 0)
}
void FitInterface::assumeXXCorrelated(const Index i1, const Index i2,
const bool isCorrelated)
{
int val = (isCorrelated) ? 1 : 0;
isXXCorr_(i1, i2) = val;
isXXCorr_(i2, i1) = val;
}
void FitInterface::assumeYYCorrelated(const Index j1, const Index j2,
const bool isCorrelated)
{
int val = (isCorrelated) ? 1 : 0;
isYYCorr_(j1, j2) = val;
isYYCorr_(j2, j1) = val;
}
void FitInterface::assumeYXCorrelated(const Index j, const Index i,
const bool isCorrelated)
{
int val = (isCorrelated) ? 1 : 0;
isYXCorr_(j, i) = val;
}
void FitInterface::assumeDataCorrelated(const Index k1, const Index k2,
const bool isCorrelated)
{
int val = (isCorrelated) ? 1 : 0;
isDataCorr_(k1, k2) = val;
isDataCorr_(k2, k1) = val;
}
void FitInterface::assumeDataCorrelated(const bool isCorrelated)
{
FOR_MAT(isDataCorr_, k1, k2)
{ {
if (k1 != k2) LATAN_ERROR(Logic, "cannot add an X dimension if fit data is "
"not empty");
}
else
{
xSize_.push_back(nData);
xIsExact_.push_back(isExact);
maxDataIndex_ *= nData;
createXData(name, nData);
scheduleLayoutInit();
scheduleDataCoordInit();
if (!name.empty())
{ {
assumeDataCorrelated(k1, k2, isCorrelated); xName().setName(getNXDim(), name);
} }
} }
} }
void FitInterface::fitPoint(const Index i, const bool isFitPoint) void FitInterface::addYDim(const string name)
{ {
isFitPoint_(i) = (isFitPoint) ? 1 : 0; yDataIndex_.push_back(map<Index, bool>());
createYData(name);
scheduleLayoutInit();
if (!name.empty())
{
yName().setName(getNYDim(), name);
}
} }
void FitInterface::fitPointRange(const Index k1, const Index k2, // access //////////////////////////////////////////////////////////////////////
const bool isFitPoint) Index FitInterface::getNXDim(void) const
{ {
int size = static_cast<int>(k2-k1+1); return xSize_.size();
}
Index FitInterface::getNYDim(void) const
{
return yDataIndex_.size();
}
Index FitInterface::getXSize(void) const
{
Index size = 0;
isFitPoint_.segment(k1, size) = IVec::Constant(size, (isFitPoint) ? 1 : 0); for (Index i = 0; i < getNXDim(); ++i)
{
size += getXSize(i);
}
return size;
} }
void FitInterface::fitAllPoints(const bool isFitPoint) Index FitInterface::getXSize(const Index i) const
{ {
fitPointRange(0, getNData()-1, isFitPoint); checkXDim(i);
return xSize_[i];
} }
Index FitInterface::getNData(void) const Index FitInterface::getYSize(void) const
{ {
return isFitPoint_.size(); Index size = 0;
for (Index j = 0; j < getNYDim(); ++j)
{
size += getYSize(j);
}
return size;
} }
Index FitInterface::getNFitPoint(void) const Index FitInterface::getYSize(const Index j) const
{ {
return isFitPoint_.sum(); checkYDim(j);
return static_cast<Index>(yDataIndex_[j].size());
} }
Index FitInterface::getXDim(void) const Index FitInterface::getXFitSize(void) const
{ {
return isXXCorr_.rows(); Index size = 0;
for (Index i = 0; i < getNXDim(); ++i)
{
size += getXFitSize(i);
}
return size;
} }
Index FitInterface::getYDim(void) const Index FitInterface::getXFitSize(const Index i) const
{ {
return isYYCorr_.rows(); set<Index> fitCoord;
vector<Index> v;
checkXDim(i);
for (Index j = 0; j < getNYDim(); ++j)
{
for (auto &p: yDataIndex_[j])
{
if (p.second)
{
v = dataCoord(p.first);
fitCoord.insert(v[i]);
}
}
}
return fitCoord.size();
} }
Index FitInterface::getStatXDim(void) const Index FitInterface::getYFitSize(void) const
{ {
return isXExact_.size() - isXExact_.sum(); Index size = 0;
for (Index j = 0; j < getNYDim(); ++j)
{
size += getYFitSize(j);
}
return size;
}
Index FitInterface::getYFitSize(const Index j) const
{
Index size;
auto pred = [](const pair<Index, bool> &p)
{
return p.second;
};
checkYDim(j);
size = count_if(yDataIndex_[j].begin(), yDataIndex_[j].end(), pred);
return size;
}
Index FitInterface::getMaxDataIndex(void) const
{
return maxDataIndex_;
}
const set<Index> & FitInterface::getDataIndexSet(void) const
{
return dataIndexSet_;
} }
double FitInterface::getSvdTolerance(void) const double FitInterface::getSvdTolerance(void) const
{ {
return svdTolerance_; return svdTol_;
} }
void FitInterface::setFitInterface(const FitInterface &fitInterface) void FitInterface::setSvdTolerance(const double &tol)
{ {
if (&fitInterface != this) svdTol_ = tol;
}
VarName & FitInterface::xName(void)
{
return xName_;
}
const VarName & FitInterface::xName(void) const
{
return xName_;
}
VarName & FitInterface::yName(void)
{
return yName_;
}
const VarName & FitInterface::yName(void) const
{
return yName_;
}
// Y dimension index helper ////////////////////////////////////////////////////
Index FitInterface::dataIndex(const vector<Index> &v) const
{
Index k, n = v.size();
checkDataCoord(v);
k = xSize_[1]*v[0];
for (unsigned int d = 1; d < n-1; ++d)
{ {
isXExact_ = fitInterface.isXExact_; k = xSize_[d+1]*(v[d] + k);
isFitPoint_ = fitInterface.isFitPoint_; }
isXXCorr_ = fitInterface.isXXCorr_; k += v[n-1];
isYYCorr_ = fitInterface.isYYCorr_;
isYXCorr_ = fitInterface.isYXCorr_; return k;
isDataCorr_ = fitInterface.isDataCorr_; }
svdTolerance_ = fitInterface.svdTolerance_;
const vector<Index> & FitInterface::dataCoord(const Index k) const
{
checkDataIndex(k);
updateDataCoord();
return dataCoord_.at(k);
}
// enable fit points ///////////////////////////////////////////////////////////
void FitInterface::fitPoint(const bool isFitPoint, const Index k, const Index j)
{
checkPoint(k, j);
yDataIndex_[j][k] = isFitPoint;
scheduleLayoutInit();
}
// variance interface //////////////////////////////////////////////////////////
void FitInterface::assumeXExact(const bool isExact, const Index i)
{
checkXDim(i);
xIsExact_[i] = isExact;
scheduleLayoutInit();
}
void FitInterface::addCorr(set<array<Index, 4>> &s, const bool isCorr,
const array<Index, 4> &c)
{
if (isCorr)
{
s.insert(c);
}
else
{
auto it = s.find(c);
if (it != s.end())
{
s.erase(it);
}
} }
} }
void FitInterface::setNData(const Index nData) void FitInterface::assumeXXCorrelated(const bool isCorr, const Index r1,
const Index i1, const Index r2,
const Index i2)
{ {
resize(nData, getXDim(), getYDim()); array<Index, 4> c{{r1, i1, r2, i2}};
checkXIndex(r1, i1);
checkXIndex(r2, i2);
if ((i1 != i2) or (r1 != r2))
{
addCorr(xxCorr_, isCorr, c);
}
scheduleFitVarMatInit();
} }
void FitInterface::setXDim(const Index xDim) void FitInterface::assumeXXCorrelated(const bool isCorr, const Index i1,
const Index i2)
{ {
resize(getNData(), xDim, getYDim()); for (Index r1 = 0; r1 < getXSize(i1); ++r1)
for (Index r2 = 0; r2 < getXSize(i2); ++r2)
{
assumeXXCorrelated(isCorr, r1, i1, r2, i2);
}
} }
void FitInterface::setYDim(const Index yDim) void FitInterface::assumeYYCorrelated(const bool isCorr, const Index k1,
const Index j1, const Index k2,
const Index j2)
{ {
resize(getNData(), getXDim(), yDim); array<Index, 4> c{{k1, j1, k2, j2}};
checkPoint(k1, j1);
checkPoint(k2, j2);
if ((j1 != j2) or (k1 != k2))
{
addCorr(yyCorr_, isCorr, c);
}
scheduleFitVarMatInit();
} }
void FitInterface::setSvdTolerance(const double tolerance) void FitInterface::assumeYYCorrelated(const bool isCorr, const Index j1,
const Index j2)
{ {
svdTolerance_ = tolerance; checkYDim(j1);
checkYDim(j2);
for (auto &p1: yDataIndex_[j1])
for (auto &p2: yDataIndex_[j2])
{
assumeYYCorrelated(isCorr, p1.first, j1, p2.first, j2);
}
} }
void FitInterface::resize(const Index nData, const Index xDim, const Index yDim) void FitInterface::assumeXYCorrelated(const bool isCorr, const Index r,
const Index i, const Index k,
const Index j)
{ {
isXExact_.setConstant(xDim, 0); array<Index, 4> c{{r, i, k, j}};
isFitPoint_.setConstant(nData, 0);
isXXCorr_.setIdentity(xDim, xDim); checkXIndex(r, i);
isYYCorr_.setIdentity(yDim, yDim); checkPoint(k, j);
isYXCorr_.setConstant(yDim, xDim, 0); addCorr(xyCorr_, isCorr, c);
isDataCorr_.setIdentity(nData, nData); scheduleFitVarMatInit();
} }
// test //////////////////////////////////////////////////////////////////////// void FitInterface::assumeXYCorrelated(const bool isCorr, const Index i,
bool FitInterface::isFitPoint(const Index k) const const Index j)
{ {
return (isFitPoint_[k] == 1); checkYDim(j);
for (Index r = 0; r < getXSize(i); ++r)
for (auto &p: yDataIndex_[j])
{
assumeXYCorrelated(isCorr, r, i, p.first, j);
}
}
// tests ///////////////////////////////////////////////////////////////////////
bool FitInterface::pointExists(const Index k) const
{
bool isUsed = false;
for (Index j = 0; j < getNYDim(); ++j)
{
isUsed = isUsed or pointExists(k, j);
}
return isUsed;
}
bool FitInterface::pointExists(const Index k, const Index j) const
{
checkDataIndex(k);
checkYDim(j);
return !(yDataIndex_[j].find(k) == yDataIndex_[j].end());
} }
bool FitInterface::isXExact(const Index i) const bool FitInterface::isXExact(const Index i) const
{ {
return (isXExact_[i] == 1); checkXDim(i);
return xIsExact_[i];
} }
bool FitInterface::isXXCorrelated(const Index i1, const Index i2) const bool FitInterface::isXUsed(const Index r, const Index i, const bool inFit) const
{ {
return (isXXCorr_(i1, i2) == 1); vector<Index> v;
checkXDim(i);
for (Index j = 0; j < getNYDim(); ++j)
{
for (auto &p: yDataIndex_[j])
{
if (p.second or !inFit)
{
v = dataCoord(p.first);
if (v[i] == r)
{
return true;
}
}
}
}
return false;
} }
bool FitInterface::isYYCorrelated(const Index j1, const Index j2) const bool FitInterface::isFitPoint(const Index k, const Index j) const
{ {
return (isYYCorr_(j1, j2) == 1); checkPoint(k, j);
return yDataIndex_[j].at(k);
} }
bool FitInterface::isYXCorrelated(const Index j, const Index i) const bool FitInterface::isXXCorrelated(const Index r1, const Index i1,
const Index r2, const Index i2) const
{ {
return (isYXCorr_(j, i) == 1); array<Index, 4> c{{r1, i1, r2, i2}};
auto it = xxCorr_.find(c);
return (it != xxCorr_.end());
} }
bool FitInterface::isDataCorrelated(const Index k1, const Index k2) const bool FitInterface::isYYCorrelated(const Index k1, const Index j1,
const Index k2, const Index j2) const
{ {
return (isDataCorr_(k1, k2) == 1); array<Index, 4> c{{k1, j1, k2, j2}};
auto it = yyCorr_.find(c);
return (it != yyCorr_.end());
}
bool FitInterface::isXYCorrelated(const Index r, const Index i,
const Index k, const Index j) const
{
array<Index, 4> c{{r, i, k, j}};
auto it = xyCorr_.find(c);
return (it != xyCorr_.end());
}
bool FitInterface::hasCorrelations(void) const
{
return ((xxCorr_.size() != 0) or (yyCorr_.size() != 0)
or (xyCorr_.size() != 0));
}
// make correlation filter for fit variance matrix /////////////////////////////
DMat FitInterface::makeCorrFilter(void)
{
updateLayout();
DMat f = DMat::Identity(layout.totalSize, layout.totalSize);
Index row, col;
for (auto &c: xxCorr_)
{
row = indX(c[0], c[1]);
col = indX(c[2], c[3]);
if ((row != -1) and (col != -1))
{
f(row, col) = 1.;
f(col, row) = 1.;
}
}
for (auto &c: yyCorr_)
{
row = indY(c[0], c[1]);
col = indY(c[2], c[3]);
if ((row != -1) and (col != -1))
{
f(row, col) = 1.;
f(col, row) = 1.;
}
}
for (auto &c: xyCorr_)
{
row = indX(c[0], c[1]);
col = indY(c[2], c[3]);
if ((row != -1) and (col != -1))
{
f(row, col) = 1.;
f(col, row) = 1.;
}
}
return f;
}
// schedule variance matrix initialization /////////////////////////////////////
void FitInterface::scheduleFitVarMatInit(const bool init)
{
initVarMat_ = init;
}
// register a data point ///////////////////////////////////////////////////////
void FitInterface::registerDataPoint(const Index k, const Index j)
{
checkYDim(j);
yDataIndex_[j][k] = true;
dataIndexSet_.insert(k);
scheduleLayoutInit();
}
// coordinate buffering ////////////////////////////////////////////////////////
void FitInterface::scheduleDataCoordInit(void)
{
initDataCoord_ = true;
scheduleFitVarMatInit();
}
void FitInterface::updateDataCoord(void) const
{
FitInterface * modThis = const_cast<FitInterface *>(this);
if (initDataCoord_)
{
modThis->dataCoord_.clear();
for (auto k: getDataIndexSet())
{
modThis->dataCoord_[k] = rowMajToCoord(k);
}
modThis->initDataCoord_ = false;
}
}
// global layout management ////////////////////////////////////////////////////
void FitInterface::scheduleLayoutInit(void)
{
initLayout_ = true;
scheduleFitVarMatInit();
}
bool FitInterface::initVarMat(void) const
{
return initVarMat_;
}
void FitInterface::updateLayout(void) const
{
if (initLayout_)
{
FitInterface * modThis = const_cast<FitInterface *>(this);
Layout & l = modThis->layout;
Index size, ifit;
vector<Index> v;
l.nXFitDim = 0;
l.nYFitDim = 0;
l.totalSize = 0;
l.totalXSize = 0;
l.totalYSize = 0;
l.xSize.clear();
l.ySize.clear();
l.dataIndexSet.clear();
l.xDim.clear();
l.yDim.clear();
l.xFitDim.clear();
l.yFitDim.clear();
l.x.clear();
l.y.clear();
l.xFit.clear();
l.yFit.clear();
ifit = 0;
for (Index i = 0; i < getNXDim(); ++i)
{
if (!xIsExact_[i])
{
l.nXFitDim++;
size = getXFitSize(i);
l.xSize.push_back(size);
l.totalXSize += size;
l.xDim.push_back(i);
l.xFitDim.push_back(layout.xDim.size() - 1);
l.x.push_back(vector<Index>());
l.xFit.push_back(vector<Index>());
for (Index r = 0; r < getXSize(i); ++r)
{
if (isXUsed(r, i))
{
l.x[ifit].push_back(r);
l.xFit[i].push_back(layout.x[ifit].size() - 1);
}
else
{
l.xFit[i].push_back(-1);
}
}
ifit++;
}
else
{
l.xFitDim.push_back(-1);
l.xFit.push_back(vector<Index>());
for (Index r = 0; r < getXSize(i); ++r)
{
l.xFit[i].push_back(-1);
}
}
}
for (Index j = 0; j < getNYDim(); ++j)
{
Index s = 0;
l.nYFitDim++;
size = getYFitSize(j);
l.ySize.push_back(size);
l.totalYSize += size;
l.yDim.push_back(j);
l.yFitDim.push_back(layout.yDim.size() - 1);
l.y.push_back(vector<Index>());
l.yFit.push_back(vector<Index>());
l.data.push_back(vector<Index>());
l.yFitFromData.push_back(map<Index, Index>());
for (auto &p: yDataIndex_[j])
{
if (p.second)
{
l.dataIndexSet.insert(p.first);
l.y[j].push_back(s);
l.yFit[j].push_back(layout.y[j].size() - 1);
l.data[j].push_back(p.first);
l.yFitFromData[j][p.first] = layout.y[j].size() - 1;
}
else
{
l.yFit[j].push_back(-1);
l.yFitFromData[j][p.first] = -1;
}
s++;
}
}
l.totalSize = layout.totalXSize + layout.totalYSize;
l.nXFitDim = static_cast<Index>(layout.xSize.size());
l.nYFitDim = static_cast<Index>(layout.ySize.size());
l.xIndFromData.resize(getMaxDataIndex());
for (Index k: layout.dataIndexSet)
{
v = dataCoord(k);
for (Index i = 0; i < getNXDim(); ++i)
{
l.xIndFromData[k].push_back(indX(v[i], i));
}
}
modThis->initLayout_ = false;
}
}
Index FitInterface::indX(const Index r, const Index i) const
{
Index ind = -1;
if (layout.xFit[i][r] != -1)
{
Index ifit = layout.xFitDim[i], rfit = layout.xFit[i][r];
ind = layout.totalYSize;
for (Index a = 0; a < ifit; ++a)
{
ind += layout.xSize[a];
}
ind += rfit;
}
return ind;
}
Index FitInterface::indY(const Index k, const Index j) const
{
Index ind = -1;
if (layout.yFitFromData[j].at(k) != -1)
{
Index jfit = layout.yFitDim[j], sfit = layout.yFitFromData[j].at(k);
ind = 0;
for (Index b = 0; b < jfit; ++b)
{
ind += layout.ySize[b];
}
ind += sfit;
}
return ind;
}
// function to convert an row-major index into coordinates /////////////////////
vector<Index> FitInterface::rowMajToCoord(const Index k) const
{
vector<Index> v(getNXDim());
Index buf, dimProd;
checkDataIndex(k);
buf = k;
dimProd = 1;
for (Index d = getNXDim() - 1; d >= 0; --d)
{
v[d] = (buf/dimProd)%xSize_[d];
buf -= dimProd*v[d];
dimProd *= xSize_[d];
}
return v;
}
// IO //////////////////////////////////////////////////////////////////////////
ostream & Latan::operator<<(ostream &out, FitInterface &f)
{
out << "X dimensions: " << f.getNXDim() << endl;
for (Index i = 0; i < f.getNXDim(); ++i)
{
out << " * " << i << " \"" << f.xName().getName(i) << "\": ";
out << f.getXSize(i) << " value(s)";
if (f.isXExact(i))
{
out << " (assumed exact)";
}
out << endl;
}
out << "Y dimensions: " << f.getNYDim() << endl;
for (Index j = 0; j < f.getNYDim(); ++j)
{
out << " * " << j << " \"" << f.yName().getName(j) << "\": ";
out << f.getYSize(j) << " value(s)" << endl;
for (auto &p: f.yDataIndex_[j])
{
out << " " << setw(3) << p.first << " (";
for (auto vi: f.dataCoord(p.first))
{
out << vi << ",";
}
out << "\b) fit: " << (p.second ? "true" : "false") << endl;
}
}
out << "X/X correlations (r1 i1 r2 i2): ";
if (f.xxCorr_.empty())
{
out << "no" << endl;
}
else
{
out << endl;
for (auto &c: f.xxCorr_)
{
out << " * ";
for (auto i: c)
{
out << i << " ";
}
out << endl;
}
}
out << "Y/Y correlations (k1 j1 k2 j2): ";
if (f.yyCorr_.empty())
{
out << "no" << endl;
}
else
{
out << endl;
for (auto &c: f.yyCorr_)
{
out << " * ";
for (auto i: c)
{
out << i << " ";
}
out << endl;
}
}
out << "X/Y correlations (r i k j): ";
if (f.xyCorr_.empty())
{
out << "no";
}
else
{
out << endl;
for (auto &c: f.xyCorr_)
{
out << " * ";
for (auto i: c)
{
out << i << " ";
}
out << endl;
}
}
return out;
} }

View File

@ -1,7 +1,7 @@
/* /*
* FitInterface.hpp, part of LatAnalyze 3 * FitInterface.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -21,63 +21,208 @@
#define Latan_FitInterface_hpp_ #define Latan_FitInterface_hpp_
#include <LatAnalyze/Global.hpp> #include <LatAnalyze/Global.hpp>
#include <LatAnalyze/Minimizer.hpp> #include <LatAnalyze/Mat.hpp>
BEGIN_LATAN_NAMESPACE BEGIN_LATAN_NAMESPACE
/****************************************************************************** /******************************************************************************
* base class for data fit * * FitInterface *
******************************************************************************/ ******************************************************************************/
class FitInterface class FitInterface
{ {
private:
typedef struct
{
Index nXFitDim, nYFitDim;
// X/Y block sizes
Index totalSize, totalXSize, totalYSize;
// size of each X/Y dimension
std::vector<Index> xSize, ySize;
// set of active data indices
std::set<Index> dataIndexSet;
// lookup tables
// xDim : x fit dim ifit -> x dim i
// x : x fit point ifit,rfit -> x point r
// xFitDim : x dim i -> x fit dim ifit (-1 if empty)
// xFit : x point i,r -> x fit point rfit (-1 if empty)
// data : y fit point jfit,sfit -> y point index k
// yFitFromData: y point index k,j -> y fit point sfit (-1 if empty)
// xIndFromData: data index k -> index of coordinates of associated x
std::vector<Index> xDim, yDim, xFitDim, yFitDim;
std::vector<std::vector<Index>> x, y, data, xFit, yFit;
std::vector<std::map<Index, Index>> yFitFromData;
// no map here for fit performance
std::vector<std::vector<Index>> xIndFromData;
} Layout;
public: public:
typedef Minimizer::Verbosity FitVerbosity; // constructor
public: FitInterface(void);
// constructors
FitInterface(void) = default;
FitInterface(const Index nData, const Index xDim, const Index yDim);
// destructor // destructor
virtual ~FitInterface(void) = default; virtual ~FitInterface(void) = default;
// copy object (not as a constructor to be accessed from derived class)
void copyInterface(const FitInterface &d);
// add dimensions
void addXDim(const Index nData, const std::string name = "",
const bool isExact = false);
void addYDim(const std::string name = "");
// access // access
void assumeXExact(const Index i, const bool isExact = true); Index getNXDim(void) const;
void assumeXXCorrelated(const Index i1, const Index i2, Index getNYDim(void) const;
const bool isCorrelated = true); Index getXSize(void) const;
void assumeYYCorrelated(const Index j1, const Index j2, Index getXSize(const Index i) const;
const bool isCorrelated = true); Index getYSize(void) const;
void assumeYXCorrelated(const Index j, const Index i, Index getYSize(const Index j) const;
const bool isCorrelated = true); Index getXFitSize(void) const;
void assumeDataCorrelated(const Index k1, const Index k2, Index getXFitSize(const Index i) const;
const bool isCorrelated = true); Index getYFitSize(void) const;
void assumeDataCorrelated(const bool isCorrelated = true); Index getYFitSize(const Index j) const;
void fitPoint(const Index k, const bool isFitPoint = true); Index getMaxDataIndex(void) const;
void fitPointRange(const Index k1, const Index k2, const std::set<Index> & getDataIndexSet(void) const;
const bool isFitPoint = true); double getSvdTolerance(void) const;
void fitAllPoints(const bool isFitPoint = true); void setSvdTolerance(const double &tol);
Index getNData(void) const; VarName & xName(void);
Index getNFitPoint(void) const; const VarName & xName(void) const;
Index getXDim(void) const; VarName & yName(void);
Index getYDim(void) const; const VarName & yName(void) const;
Index getStatXDim(void) const;
double getSvdTolerance(void) const; // Y dimension index helper
void setFitInterface(const FitInterface &fitInterface); template <typename... Ts>
void setNData(const Index nData); Index dataIndex(const Ts... is) const;
void setXDim(const Index xDim); Index dataIndex(const std::vector<Index> &v) const;
void setYDim(const Index yDim); const std::vector<Index> & dataCoord(const Index k) const;
void setSvdTolerance(const double tolerance); // enable fit points
void resize(const Index nData, const Index xDim, const Index yDim); void fitPoint(const bool isFitPoint, const Index k, const Index j = 0);
// test // variance interface
bool isFitPoint(const Index k) const; void assumeXExact(const bool isExact, const Index i);
void assumeXXCorrelated(const bool isCorr, const Index r1, const Index i1,
const Index r2, const Index i2);
void assumeXXCorrelated(const bool isCorr, const Index i1, const Index i2);
void assumeYYCorrelated(const bool isCorr, const Index k1, const Index j1,
const Index k2, const Index j2);
void assumeYYCorrelated(const bool isCorr, const Index j1, const Index j2);
void assumeXYCorrelated(const bool isCorr, const Index r, const Index i,
const Index k, const Index j);
void assumeXYCorrelated(const bool isCorr, const Index i, const Index j);
// tests
bool pointExists(const Index k) const;
bool pointExists(const Index k, const Index j) const;
bool isXExact(const Index i) const; bool isXExact(const Index i) const;
bool isXXCorrelated(const Index i1, const Index i2) const; bool isXUsed(const Index r, const Index i, const bool inFit = true) const;
bool isYYCorrelated(const Index j1, const Index j2) const; bool isFitPoint(const Index k, const Index j) const;
bool isYXCorrelated(const Index j, const Index i) const; bool isXXCorrelated(const Index r1, const Index i1, const Index r2,
bool isDataCorrelated(const Index k1, const Index k2) const; const Index i2) const;
bool isYYCorrelated(const Index k1, const Index j1, const Index k2,
const Index j2) const;
bool isXYCorrelated(const Index r, const Index i, const Index k,
const Index j) const;
bool hasCorrelations(void) const;
// make correlation filter for fit variance matrix
DMat makeCorrFilter(void);
// schedule variance matrix initialization
void scheduleFitVarMatInit(const bool init = true);
// IO
friend std::ostream & operator<<(std::ostream &out, FitInterface &f);
protected:
// register a data point
void registerDataPoint(const Index k, const Index j = 0);
// add correlation to a set
static void addCorr(std::set<std::array<Index, 4>> &s, const bool isCorr,
const std::array<Index, 4> &c);
// abstract methods to create data containers
virtual void createXData(const std::string name, const Index nData) = 0;
virtual void createYData(const std::string name) = 0;
// coordinate buffering
void scheduleDataCoordInit(void);
void updateDataCoord(void) const;
// global layout management
void scheduleLayoutInit(void);
bool initVarMat(void) const;
void updateLayout(void) const;
Index indX(const Index r, const Index i) const;
Index indY(const Index k, const Index j) const;
private: private:
IVec isXExact_, isFitPoint_; // function to convert an row-major index into coordinates
IMat isXXCorr_, isYYCorr_, isYXCorr_, isDataCorr_; std::vector<Index> rowMajToCoord(const Index k) const;
double svdTolerance_{1.0e-10}; protected:
Layout layout;
private:
VarName xName_, yName_;
std::vector<Index> xSize_;
std::vector<bool> xIsExact_;
std::map<Index, std::vector<Index>> dataCoord_;
std::set<Index> dataIndexSet_;
std::vector<std::map<Index, bool>> yDataIndex_;
std::set<std::array<Index, 4>> xxCorr_, yyCorr_, xyCorr_;
Index maxDataIndex_{1};
bool initLayout_{true};
bool initVarMat_{true};
bool initDataCoord_{true};
double svdTol_{1.e-10};
}; };
std::ostream & operator<<(std::ostream &out, FitInterface &f);
/******************************************************************************
* FitInterface template implementation *
******************************************************************************/
// Y dimension index helper ////////////////////////////////////////////////////
template <typename... Ts>
Index FitInterface::dataIndex(const Ts... coords) const
{
static_assert(static_or<std::is_convertible<Index, Ts>::value...>::value,
"fitPoint arguments are not compatible with Index");
const std::vector<Index> coord = {coords...};
return dataIndex(coord);
}
/******************************************************************************
* error check macros *
******************************************************************************/
#define checkXDim(i)\
if ((i) >= getNXDim())\
{\
LATAN_ERROR(Range, "X dimension " + strFrom(i) + " out of range");\
}
#define checkXIndex(vi, i)\
if ((vi) >= getXSize(i))\
{\
LATAN_ERROR(Range, "index " + strFrom(vi) + " in X dimension "\
+ strFrom(i) + " out of range");\
}
#define checkYDim(j)\
if ((j) >= getNYDim())\
{\
LATAN_ERROR(Range, "Y dimension " + strFrom(j) + " out of range");\
}
#define checkDataIndex(k)\
if ((k) >= getMaxDataIndex())\
{\
LATAN_ERROR(Range, "data point index " + strFrom(k) + " invalid");\
}
#define checkDataCoord(v)\
if (static_cast<Index>((v).size()) != getNXDim())\
{\
LATAN_ERROR(Size, "number of coordinates and number of X dimensions "\
"mismatch");\
}\
for (unsigned int i_ = 0; i_ < (v).size(); ++i_)\
{\
checkXIndex((v)[i_], i_);\
}
#define checkPoint(k, j)\
if (!pointExists(k, j))\
{\
LATAN_ERROR(Range, "no data point in Y dimension " + strFrom(j)\
+ " with index " + strFrom(k));\
}
END_LATAN_NAMESPACE END_LATAN_NAMESPACE
#endif // Latan_FitInterface_hpp_ #endif // Latan_FitInterface_hpp_

View File

@ -1,7 +1,7 @@
/* /*
* Function.cpp, part of LatAnalyze 3 * Function.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -29,6 +29,7 @@ using namespace Latan;
// constructor ///////////////////////////////////////////////////////////////// // constructor /////////////////////////////////////////////////////////////////
DoubleFunction::DoubleFunction(const vecFunc &f, const Index nArg) DoubleFunction::DoubleFunction(const vecFunc &f, const Index nArg)
: buffer_(new DVec) : buffer_(new DVec)
, varName_("x")
{ {
setFunction(f, nArg); setFunction(f, nArg);
} }
@ -45,6 +46,16 @@ void DoubleFunction::setFunction(const vecFunc &f, const Index nArg)
f_ = f; f_ = f;
} }
VarName & DoubleFunction::varName(void)
{
return varName_;
}
const VarName & DoubleFunction::varName(void) const
{
return varName_;
}
// error checking ////////////////////////////////////////////////////////////// // error checking //////////////////////////////////////////////////////////////
void DoubleFunction::checkSize(const Index nPar) const void DoubleFunction::checkSize(const Index nPar) const
{ {

View File

@ -1,7 +1,7 @@
/* /*
* Function.hpp, part of LatAnalyze 3 * Function.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -23,9 +23,6 @@
#include <LatAnalyze/Global.hpp> #include <LatAnalyze/Global.hpp>
#include <LatAnalyze/Mat.hpp> #include <LatAnalyze/Mat.hpp>
#include <LatAnalyze/MatSample.hpp> #include <LatAnalyze/MatSample.hpp>
#include <functional>
#include <stack>
#include <vector>
BEGIN_LATAN_NAMESPACE BEGIN_LATAN_NAMESPACE
@ -43,8 +40,10 @@ public:
// destructor // destructor
virtual ~DoubleFunction(void) = default; virtual ~DoubleFunction(void) = default;
// access // access
virtual Index getNArg(void) const; virtual Index getNArg(void) const;
void setFunction(const vecFunc &f, const Index nArg); void setFunction(const vecFunc &f, const Index nArg);
VarName & varName(void);
const VarName & varName(void) const;
// function call // function call
double operator()(const double *arg) const; double operator()(const double *arg) const;
double operator()(const DVec &arg) const; double operator()(const DVec &arg) const;
@ -75,6 +74,7 @@ private:
void checkSize(const Index nPar) const; void checkSize(const Index nPar) const;
private: private:
std::shared_ptr<DVec> buffer_{nullptr}; std::shared_ptr<DVec> buffer_{nullptr};
VarName varName_;
vecFunc f_; vecFunc f_;
}; };

View File

@ -1,7 +1,7 @@
/* /*
* Global.cpp, part of LatAnalyze 3 * Global.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -23,6 +23,8 @@
using namespace std; using namespace std;
using namespace Latan; using namespace Latan;
PlaceHolder Latan::_;
const string Env::fullName = PACKAGE_STRING; const string Env::fullName = PACKAGE_STRING;
const string Env::name = PACKAGE_NAME; const string Env::name = PACKAGE_NAME;
const string Env::version = PACKAGE_VERSION; const string Env::version = PACKAGE_VERSION;

View File

@ -1,7 +1,7 @@
/* /*
* Global.hpp, part of LatAnalyze 3 * Global.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
* GslHybridRootFinder.cpp, part of LatAnalyze 3 * GslHybridRootFinder.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
* GslHybridRootFinder.hpp, part of LatAnalyze 3 * GslHybridRootFinder.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

361
lib/GslMinimizer.cpp Normal file
View File

@ -0,0 +1,361 @@
/*
* GslMinimizer.cpp, part of LatAnalyze
*
* Copyright (C) 2013 - 2016 Antonin Portelli
*
* LatAnalyze is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LatAnalyze 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LatAnalyze. If not, see <http://www.gnu.org/licenses/>.
*/
#include <LatAnalyze/GslMinimizer.hpp>
#include <LatAnalyze/includes.hpp>
#include <LatAnalyze/Math.hpp>
#include <gsl/gsl_multimin.h>
#include <gsl/gsl_blas.h>
using namespace std;
using namespace Latan;
/******************************************************************************
* GslMinimizer implementation *
******************************************************************************/
// constructor /////////////////////////////////////////////////////////////////
GslMinimizer::GslMinimizer(const Algorithm algorithm)
{
setAlgorithm(algorithm);
der_.setOrder(1, 1);
}
// access //////////////////////////////////////////////////////////////////////
GslMinimizer::Algorithm GslMinimizer::getAlgorithm(void) const
{
return algorithm_;
}
void GslMinimizer::setAlgorithm(const Algorithm algorithm)
{
algorithm_ = algorithm;
}
bool GslMinimizer::supportLimits(void) const
{
return false;
}
// test ////////////////////////////////////////////////////////////////////////
bool GslMinimizer::isDerAlgorithm(const Algorithm algorithm)
{
return (algorithm <= Algorithm::lastDerAlg);
}
// minimization ////////////////////////////////////////////////////////////////
const DVec & GslMinimizer::operator()(const DoubleFunction &f)
{
DVec &x = getState();
// resize minimizer state to match function number of arguments
if (f.getNArg() != x.size())
{
resize(f.getNArg());
}
// set function data
GslFuncData data;
der_.setFunction(f);
data.f = &f;
data.d = &der_;
// set initial position
gsl_vector *gslX = gsl_vector_alloc(getDim());
for (Index i = 0; i < getDim(); ++i)
{
gsl_vector_set(gslX, i, x(i));
}
// minimization
int status;
if (isDerAlgorithm(getAlgorithm()))
{
// set function
gsl_multimin_function_fdf gslFunc;
gslFunc.n = getDim();
gslFunc.f = &fWrapper;
gslFunc.df = &dfWrapper;
gslFunc.fdf = &fdfWrapper;
gslFunc.params = &data;
// create and set minimizer
const gsl_multimin_fdfminimizer_type *gslAlg;
gsl_multimin_fdfminimizer *gslMin;
switch (getAlgorithm())
{
case Algorithm::cgFR:
gslAlg = gsl_multimin_fdfminimizer_conjugate_fr;
break;
case Algorithm::cgPR:
gslAlg = gsl_multimin_fdfminimizer_conjugate_pr;
break;
case Algorithm::bfgs:
gslAlg = gsl_multimin_fdfminimizer_vector_bfgs;
break;
case Algorithm::bfgs2:
gslAlg = gsl_multimin_fdfminimizer_vector_bfgs2;
break;
case Algorithm::steepDesc:
gslAlg = gsl_multimin_fdfminimizer_vector_bfgs2;
break;
default:
LATAN_ERROR(Argument, "unknow GSL minization algorithm "
+ strFrom(static_cast<int>(getAlgorithm())));
break;
}
gslMin = gsl_multimin_fdfminimizer_alloc(gslAlg, getDim());
// minimize
unsigned int pass = 0, it;
double dxRel;
do
{
pass++;
gsl_multimin_fdfminimizer_set(gslMin, &gslFunc, gslX, 0.01, 0.001);
if (getVerbosity() >= Verbosity::Normal)
{
cout << "========== GSL minimization, pass #" << pass;
cout << " ==========" << endl;
cout << "Algorithm: " << getAlgorithmName(getAlgorithm());
cout << endl;
cout << "Max eval.= " << getMaxIteration();
cout << " -- Precision= " << getPrecision() << endl;
printf("Starting f(x)= %.10e\n", f(x));
}
it = 0;
do
{
it++;
gsl_multimin_fdfminimizer_iterate(gslMin);
dxRel = gsl_blas_dnrm2(gslMin->dx)/gsl_blas_dnrm2(gslMin->x);
status = (dxRel < getPrecision()) ? GSL_SUCCESS : GSL_CONTINUE;
if (getVerbosity() >= Verbosity::Debug)
{
printf("iteration %4d: f= %.10e dxrel= %.10e eval= %d\n",
it, gslMin->f, dxRel, data.evalCount);
}
} while (status == GSL_CONTINUE and
(data.evalCount < getMaxIteration()));
if (getVerbosity() >= Verbosity::Normal)
{
printf("Found minimum %.10e at:\n", gslMin->f);
for (Index i = 0; i < x.size(); ++i)
{
printf("%8s= %.10e\n", f.varName().getName(i).c_str(),
gsl_vector_get(gslMin->x, i));
}
cout << "after " << data.evalCount << " evaluations" << endl;
cout << "Minimization ended with code " << status;
cout << endl;
}
data.evalCount = 0;
for (Index i = 0; i < getDim(); ++i)
{
gsl_vector_set(gslX, i, gsl_vector_get(gslMin->x, i));
}
} while (status != GSL_SUCCESS and (pass < getMaxPass()));
// deallocate GSL minimizer
gsl_multimin_fdfminimizer_free(gslMin);
}
else
{
// set function
gsl_multimin_function gslFunc;
gslFunc.n = getDim();
gslFunc.f = &fWrapper;
gslFunc.params = &data;
// create and set minimizer
const gsl_multimin_fminimizer_type *gslAlg;
gsl_multimin_fminimizer *gslMin;
switch (getAlgorithm())
{
case Algorithm::simplex:
gslAlg = gsl_multimin_fminimizer_nmsimplex;
break;
case Algorithm::simplex2:
gslAlg = gsl_multimin_fminimizer_nmsimplex2;
break;
case Algorithm::simplex2R:
gslAlg = gsl_multimin_fminimizer_nmsimplex2rand;
break;
default:
LATAN_ERROR(Argument, "unknow GSL minization algorithm "
+ strFrom(static_cast<int>(getAlgorithm())));
break;
}
gslMin = gsl_multimin_fminimizer_alloc(gslAlg, getDim());
// minimize
unsigned int pass = 0, it;
gsl_vector *step = gsl_vector_alloc(getDim());
double relSize;
gsl_vector_set_all(step, 0.01);
do
{
pass++;
gsl_multimin_fminimizer_set(gslMin, &gslFunc, gslX, step);
if (getVerbosity() >= Verbosity::Normal)
{
cout << "========== GSL minimization, pass #" << pass;
cout << " ==========" << endl;
cout << "Algorithm: " << getAlgorithmName(getAlgorithm());
cout << endl;
cout << "Max eval.= " << getMaxIteration();
cout << " -- Precision= " << getPrecision() << endl;
printf("Starting f(x)= %.10e\n", f(x));
}
it = 0;
do
{
it++;
gsl_multimin_fminimizer_iterate(gslMin);
relSize = Math::pow<2>(gslMin->size)/gsl_blas_dnrm2(gslMin->x);
status = (relSize < getPrecision()) ? GSL_SUCCESS
: GSL_CONTINUE;
if (getVerbosity() >= Verbosity::Debug)
{
printf("iteration %4d: f= %.10e relSize= %.10e eval= %d\n",
it, gslMin->fval, relSize, data.evalCount);
}
} while (status == GSL_CONTINUE and
(data.evalCount < getMaxIteration()));
if (getVerbosity() >= Verbosity::Normal)
{
printf("Found minimum %.10e at:\n", gslMin->fval);
for (Index i = 0; i < x.size(); ++i)
{
printf("%8s= %.10e\n", f.varName().getName(i).c_str(),
gsl_vector_get(gslMin->x, i));
}
cout << "after " << data.evalCount << " evaluations" << endl;
cout << "Minimization ended with code " << status;
cout << endl;
}
data.evalCount = 0;
for (Index i = 0; i < getDim(); ++i)
{
gsl_vector_set(gslX, i, gsl_vector_get(gslMin->x, i));
}
} while (status != GSL_SUCCESS and (pass < getMaxPass()));
// deallocate GSL minimizer
gsl_multimin_fminimizer_free(gslMin);
gsl_vector_free(step);
}
if (status != GSL_SUCCESS)
{
LATAN_WARNING("invalid minimum: maximum number of call reached");
}
// save final result
for (Index i = 0; i < getDim(); ++i)
{
x(i) = gsl_vector_get(gslX, i);
}
// deallocate GSL state and return
gsl_vector_free(gslX);
return x;
}
// function wrappers ///////////////////////////////////////////////////////////
double GslMinimizer::fWrapper(const gsl_vector *x, void *vdata)
{
GslFuncData &data = *static_cast<GslFuncData *>(vdata);
data.evalCount++;
return (*data.f)(x->data);
}
void GslMinimizer::dfWrapper(const gsl_vector *x, void *vdata, gsl_vector * df)
{
GslFuncData &data = *static_cast<GslFuncData *>(vdata);
const unsigned int n = data.f->getNArg();
for (unsigned int i = 0; i < n; ++i)
{
data.d->setDir(i);
gsl_vector_set(df, i, (*(data.d))(x->data));
}
data.evalCount += data.d->getNPoint()*n;
}
void GslMinimizer::fdfWrapper(const gsl_vector *x, void *vdata, double *f,
gsl_vector * df)
{
GslFuncData &data = *static_cast<GslFuncData *>(vdata);
const unsigned int n = data.f->getNArg();
for (unsigned int i = 0; i < n; ++i)
{
data.d->setDir(i);
gsl_vector_set(df, i, (*(data.d))(x->data));
}
*f = (*data.f)(x->data);
data.evalCount += data.d->getNPoint()*n + 1;
}
// algorithm names /////////////////////////////////////////////////////////////
string GslMinimizer::getAlgorithmName(const Algorithm algorithm)
{
switch (algorithm)
{
case Algorithm::cgFR:
return "Fletcher-Reeves conjugate gradient";
break;
case Algorithm::cgPR:
return "Polak-Ribiere conjugate gradient";
break;
case Algorithm::bfgs:
return "Broyden-Fletcher-Goldfarb-Shanno";
break;
case Algorithm::bfgs2:
return "improved Broyden-Fletcher-Goldfarb-Shanno";
break;
case Algorithm::steepDesc:
return "steepest descent";
break;
case Algorithm::simplex:
return "Nelder-Mead simplex";
break;
case Algorithm::simplex2:
return "improved Nelder-Mead simplex";
break;
case Algorithm::simplex2R:
return "improved Nelder-Mead simplex with random start";
break;
}
return "";
}

86
lib/GslMinimizer.hpp Normal file
View File

@ -0,0 +1,86 @@
/*
* GslMinimizer.hpp, part of LatAnalyze
*
* Copyright (C) 2013 - 2016 Antonin Portelli
*
* LatAnalyze is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LatAnalyze 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LatAnalyze. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Latan_GslMinimizer_hpp_
#define Latan_GslMinimizer_hpp_
#include <LatAnalyze/Global.hpp>
#include <LatAnalyze/Derivative.hpp>
#include <LatAnalyze/Function.hpp>
#include <LatAnalyze/Minimizer.hpp>
#include <gsl/gsl_vector.h>
BEGIN_LATAN_NAMESPACE
/******************************************************************************
* interface to the GSL minimizers *
******************************************************************************/
class GslMinimizer: public Minimizer
{
public:
enum class Algorithm
{
cgFR = 1,
cgPR = 2,
bfgs = 3,
bfgs2 = 4,
steepDesc = 5,
lastDerAlg = 5,
simplex = 6,
simplex2 = 7,
simplex2R = 8
};
private:
struct GslFuncData
{
const DoubleFunction *f{nullptr};
Derivative *d{nullptr};
unsigned int evalCount{0};
};
public:
// constructor
explicit GslMinimizer(const Algorithm algorithm = defaultAlg_);
// destructor
virtual ~GslMinimizer(void) = default;
// access
Algorithm getAlgorithm(void) const;
void setAlgorithm(const Algorithm algorithm);
virtual bool supportLimits(void) const;
// minimization
virtual const DVec & operator()(const DoubleFunction &f);
private:
// test
static bool isDerAlgorithm(const Algorithm algorithm);
// function wrappers
static double fWrapper(const gsl_vector *x, void * params);
static void dfWrapper(const gsl_vector *x, void * params,
gsl_vector * df);
static void fdfWrapper(const gsl_vector *x, void *params, double *f,
gsl_vector * df);
// algorithm names
std::string getAlgorithmName(const Algorithm algorithm);
private:
Algorithm algorithm_;
static constexpr Algorithm defaultAlg_ = Algorithm::simplex2;
CentralDerivative der_;
};
END_LATAN_NAMESPACE
#endif // Latan_GslMinimizer_hpp_

View File

@ -1,7 +1,7 @@
/* /*
* GslQagsIntegrator.cpp, part of LatAnalyze 3 * GslQagsIntegrator.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
* GslQagsIntegrator.hpp, part of LatAnalyze 3 * GslQagsIntegrator.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
* Hdf5File.cpp, part of LatAnalyze 3 * Hdf5File.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli, Matt Spraggs * Copyright (C) 2013 - 2016 Antonin Portelli, Matt Spraggs
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -30,8 +30,8 @@ using namespace H5NS;
constexpr unsigned int maxGroupNameSize = 1024u; constexpr unsigned int maxGroupNameSize = 1024u;
const short dMatType = static_cast<short>(IoObject::IoType::dMat); const short dMatType = static_cast<short>(IoObject::IoType::dMat);
const short dSampleType = static_cast<short>(IoObject::IoType::dSample);
const short dMatSampleType = static_cast<short>(IoObject::IoType::dMatSample); const short dMatSampleType = static_cast<short>(IoObject::IoType::dMatSample);
const short rgStateType = static_cast<short>(IoObject::IoType::rgState);
/****************************************************************************** /******************************************************************************
* Hdf5File implementation * * Hdf5File implementation *
@ -65,7 +65,6 @@ void Hdf5File::save(const DMat &m, const string &name)
hsize_t dim[2] = {static_cast<hsize_t>(m.rows()), hsize_t dim[2] = {static_cast<hsize_t>(m.rows()),
static_cast<hsize_t>(m.cols())}; static_cast<hsize_t>(m.cols())};
hsize_t attrDim = 1; hsize_t attrDim = 1;
DataSpace dataSpace(2, dim), attrSpace(1, &attrDim); DataSpace dataSpace(2, dim), attrSpace(1, &attrDim);
group = h5File_->createGroup(name.c_str() + nameOffset(name)); group = h5File_->createGroup(name.c_str() + nameOffset(name));
@ -75,7 +74,31 @@ void Hdf5File::save(const DMat &m, const string &name)
dataset.write(m.data(), PredType::NATIVE_DOUBLE); dataset.write(m.data(), PredType::NATIVE_DOUBLE);
} }
void Hdf5File::save(const DMatSample &sample, const string &name) void Hdf5File::save(const DSample &ds, const string &name)
{
if (name.empty())
{
LATAN_ERROR(Io, "trying to save data with an empty name");
}
Group group;
Attribute attr;
DataSet dataset;
hsize_t dim = static_cast<hsize_t>(ds.size() + 1);
hsize_t attrDim = 1;
DataSpace dataSpace(1, &dim), attrSpace(1, &attrDim);
const long int nSample = ds.size();
group = h5File_->createGroup(name.c_str() + nameOffset(name));
attr = group.createAttribute("type", PredType::NATIVE_SHORT, attrSpace);
attr.write(PredType::NATIVE_SHORT, &dSampleType);
attr = group.createAttribute("nSample", PredType::NATIVE_LONG, attrSpace);
attr.write(PredType::NATIVE_LONG, &nSample);
dataset = group.createDataSet("data", PredType::NATIVE_DOUBLE, dataSpace);
dataset.write(ds.data(), PredType::NATIVE_DOUBLE);
}
void Hdf5File::save(const DMatSample &ms, const string &name)
{ {
if (name.empty()) if (name.empty())
{ {
@ -85,11 +108,11 @@ void Hdf5File::save(const DMatSample &sample, const string &name)
Group group; Group group;
Attribute attr; Attribute attr;
DataSet dataset; DataSet dataset;
hsize_t dim[2] = {static_cast<hsize_t>(sample[central].rows()), hsize_t dim[2] = {static_cast<hsize_t>(ms[central].rows()),
static_cast<hsize_t>(sample[central].cols())}; static_cast<hsize_t>(ms[central].cols())};
hsize_t attrDim = 1; hsize_t attrDim = 1;
DataSpace dataSpace(2, dim), attrSpace(1, &attrDim); DataSpace dataSpace(2, dim), attrSpace(1, &attrDim);
const long int nSample = sample.size(); const long int nSample = ms.size();
string datasetName; string datasetName;
group = h5File_->createGroup(name.c_str() + nameOffset(name)); group = h5File_->createGroup(name.c_str() + nameOffset(name));
@ -97,37 +120,16 @@ void Hdf5File::save(const DMatSample &sample, const string &name)
attr.write(PredType::NATIVE_SHORT, &dMatSampleType); attr.write(PredType::NATIVE_SHORT, &dMatSampleType);
attr = group.createAttribute("nSample", PredType::NATIVE_LONG, attrSpace); attr = group.createAttribute("nSample", PredType::NATIVE_LONG, attrSpace);
attr.write(PredType::NATIVE_LONG, &nSample); attr.write(PredType::NATIVE_LONG, &nSample);
FOR_STAT_ARRAY(sample, s) FOR_STAT_ARRAY(ms, s)
{ {
datasetName = (s == central) ? "data_C" : ("data_S_" + strFrom(s)); datasetName = (s == central) ? "data_C" : ("data_S_" + strFrom(s));
dataset = group.createDataSet(datasetName.c_str(), dataset = group.createDataSet(datasetName.c_str(),
PredType::NATIVE_DOUBLE, PredType::NATIVE_DOUBLE,
dataSpace); dataSpace);
dataset.write(sample[s].data(), PredType::NATIVE_DOUBLE); dataset.write(ms[s].data(), PredType::NATIVE_DOUBLE);
} }
} }
void Hdf5File::save(const RandGenState &state, const string &name)
{
if (name.empty())
{
LATAN_ERROR(Io, "trying to save data with an empty name");
}
Group group;
Attribute attr;
DataSet dataset;
hsize_t dim = RLXG_STATE_SIZE;
hsize_t attrDim = 1;
DataSpace dataSpace(1, &dim), attrSpace(1, &attrDim);
group = h5File_->createGroup(name.c_str() + nameOffset(name));
attr = group.createAttribute("type", PredType::NATIVE_SHORT, attrSpace);
attr.write(PredType::NATIVE_SHORT, &rgStateType);
dataset = group.createDataSet("data", PredType::NATIVE_INT, dataSpace);
dataset.write(state.data(), PredType::NATIVE_INT);
}
// read first name //////////////////////////////////////////////////////////// // read first name ////////////////////////////////////////////////////////////
string Hdf5File::getFirstName(void) string Hdf5File::getFirstName(void)
{ {
@ -253,18 +255,15 @@ void Hdf5File::load(DMat &m, const DataSet &d)
d.read(m.data(), PredType::NATIVE_DOUBLE); d.read(m.data(), PredType::NATIVE_DOUBLE);
} }
void Hdf5File::load(RandGenState &state, const DataSet &d) void Hdf5File::load(DSample &ds, const DataSet &d)
{ {
DataSpace dataspace; DataSpace dataspace;
hsize_t dim[1]; hsize_t dim[1];
dataspace = d.getSpace(); dataspace = d.getSpace();
dataspace.getSimpleExtentDims(dim); dataspace.getSimpleExtentDims(dim);
if (dim[0] != RLXG_STATE_SIZE) ds.resize(dim[0] - 1);
{ d.read(ds.data(), PredType::NATIVE_DOUBLE);
LATAN_ERROR(Io, "random generator state has a wrong length");
}
d.read(state.data(), PredType::NATIVE_INT);
} }
string Hdf5File::load(const string &name) string Hdf5File::load(const string &name)
@ -296,6 +295,15 @@ string Hdf5File::load(const string &name)
load(*pt, dataset); load(*pt, dataset);
break; break;
} }
case IoObject::IoType::dSample:
{
DSample *pt = new DSample;
data_[groupName].reset(pt);
dataset = group.openDataSet("data");
load(*pt, dataset);
break;
}
case IoObject::IoType::dMatSample: case IoObject::IoType::dMatSample:
{ {
DMatSample *pt = new DMatSample; DMatSample *pt = new DMatSample;
@ -320,15 +328,6 @@ string Hdf5File::load(const string &name)
} }
break; break;
} }
case IoObject::IoType::rgState:
{
RandGenState *pt = new RandGenState;
data_[groupName].reset(pt);
dataset = group.openDataSet("data");
load(*pt, dataset);
break;
}
default: default:
{ {
LATAN_ERROR(Io, "unknown data type (" LATAN_ERROR(Io, "unknown data type ("

View File

@ -1,7 +1,7 @@
/* /*
* Hdf5File.hpp, part of LatAnalyze 3 * Hdf5File.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli, Matt Spraggs * Copyright (C) 2013 - 2016 Antonin Portelli, Matt Spraggs
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -24,7 +24,6 @@
#include <LatAnalyze/File.hpp> #include <LatAnalyze/File.hpp>
#include <LatAnalyze/Mat.hpp> #include <LatAnalyze/Mat.hpp>
#include <LatAnalyze/MatSample.hpp> #include <LatAnalyze/MatSample.hpp>
#include <LatAnalyze/RandGen.hpp>
#include <H5Cpp.h> #include <H5Cpp.h>
BEGIN_LATAN_NAMESPACE BEGIN_LATAN_NAMESPACE
@ -46,8 +45,8 @@ public:
virtual ~Hdf5File(void); virtual ~Hdf5File(void);
// access // access
virtual void save(const DMat &m, const std::string &name); virtual void save(const DMat &m, const std::string &name);
virtual void save(const DMatSample &s, const std::string &name); virtual void save(const DSample &ds, const std::string &name);
virtual void save(const RandGenState &state, const std::string &name); virtual void save(const DMatSample &ms, const std::string &name);
// read first name // read first name
virtual std::string getFirstName(void); virtual std::string getFirstName(void);
// tests // tests
@ -60,8 +59,8 @@ private:
std::string getFirstGroupName(void); std::string getFirstGroupName(void);
virtual std::string load(const std::string &name = ""); virtual std::string load(const std::string &name = "");
void load(DMat &m, const H5NS::DataSet &d); void load(DMat &m, const H5NS::DataSet &d);
void load(DSample &ds, const H5NS::DataSet &d);
void load(DMatSample &s, const H5NS::DataSet &d); void load(DMatSample &s, const H5NS::DataSet &d);
void load(RandGenState &state, const H5NS::DataSet &d);
// check name for forbidden characters // check name for forbidden characters
static size_t nameOffset(const std::string &name); static size_t nameOffset(const std::string &name);
private: private:

View File

@ -1,7 +1,7 @@
/* /*
* Histogram.cpp, part of LatAnalyze 3 * Histogram.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
* Histogram.hpp, part of LatAnalyze 3 * Histogram.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
* Integrator.hpp, part of LatAnalyze 3 * Integrator.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
* Io.cpp, part of LatAnalyze 3 * Io.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -19,6 +19,10 @@
#include <LatAnalyze/Io.hpp> #include <LatAnalyze/Io.hpp>
#include <LatAnalyze/includes.hpp> #include <LatAnalyze/includes.hpp>
#include <LatAnalyze/AsciiFile.hpp>
#ifdef HAVE_HDF5
#include <LatAnalyze/Hdf5File.hpp>
#endif
using namespace std; using namespace std;
using namespace Latan; using namespace Latan;
@ -34,14 +38,16 @@ unique_ptr<File> Io::open(const std::string &fileName, const unsigned int mode)
{ {
string ext = extension(fileName); string ext = extension(fileName);
if (ext == "h5") if ((ext == "dat")||(ext == "sample")||(ext == "seed"))
{
return unique_ptr<File>(new Hdf5File(fileName, mode));
}
else if ((ext == "dat")||(ext == "sample")||(ext == "seed"))
{ {
return unique_ptr<File>(new AsciiFile(fileName, mode)); return unique_ptr<File>(new AsciiFile(fileName, mode));
} }
#ifdef HAVE_HDF5
else if (ext == "h5")
{
return unique_ptr<File>(new Hdf5File(fileName, mode));
}
#endif
else else
{ {
LATAN_ERROR(Io, "unknown file extension '" + ext + "'"); LATAN_ERROR(Io, "unknown file extension '" + ext + "'");

View File

@ -1,7 +1,7 @@
/* /*
* Io.hpp, part of LatAnalyze 3 * Io.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -21,8 +21,7 @@
#define Latan_Io_hpp_ #define Latan_Io_hpp_
#include <LatAnalyze/Global.hpp> #include <LatAnalyze/Global.hpp>
#include <LatAnalyze/AsciiFile.hpp> #include <LatAnalyze/File.hpp>
#include <LatAnalyze/Hdf5File.hpp>
BEGIN_LATAN_NAMESPACE BEGIN_LATAN_NAMESPACE

View File

@ -1,7 +1,7 @@
/* /*
* IoObject.hpp, part of LatAnalyze 3 * IoObject.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -30,12 +30,13 @@ BEGIN_LATAN_NAMESPACE
class IoObject class IoObject
{ {
public: public:
// conserve order for datafile retro-compatibility!
enum class IoType: short int enum class IoType: short int
{ {
noType = 0, noType = 0,
dMat = 1, dMat = 1,
dMatSample = 2, dMatSample = 2,
rgState = 3 dSample = 3
}; };
public: public:
// destructor // destructor

View File

@ -1,24 +1,28 @@
COM_CXXFLAGS = -Wall -Wconversion COM_CXXFLAGS = -Wall
if CXX_GNU if CXX_GNU
COM_CXXFLAGS += -W -pedantic COM_CXXFLAGS += -W -pedantic -Wno-deprecated-declarations
else else
if CXX_INTEL if CXX_INTEL
COM_CXXFLAGS += COM_CXXFLAGS += -wd1682
endif endif
endif endif
AM_LFLAGS = -olex.yy.c AM_LFLAGS = -olex.yy.c
AM_YFLAGS = -d AM_YFLAGS = -d
BUILT_SOURCES = AsciiParser.hpp MathParser.hpp
lib_LTLIBRARIES = libLatAnalyze.la lib_LTLIBRARIES = libLatAnalyze.la
noinst_LTLIBRARIES = libLexers.la
libLexers_la_SOURCES = AsciiLexer.lpp MathLexer.lpp
if CXX_GNU
libLexers_la_CXXFLAGS = $(COM_CXXFLAGS) -Wno-unused-parameter -Wno-unused-function -Wno-deprecated-register
else
libLexers_la_CXXFLAGS = $(COM_CXXFLAGS)
endif
libLatAnalyze_la_SOURCES = \ libLatAnalyze_la_SOURCES = \
AsciiFile.cpp \ AsciiFile.cpp \
AsciiParser.ypp \ AsciiParser.ypp \
AsciiLexer.lpp \
Chi2Function.cpp \
CompiledFunction.cpp \ CompiledFunction.cpp \
CompiledModel.cpp \ CompiledModel.cpp \
Derivative.cpp \ Derivative.cpp \
@ -28,8 +32,8 @@ libLatAnalyze_la_SOURCES = \
Function.cpp \ Function.cpp \
Global.cpp \ Global.cpp \
GslHybridRootFinder.cpp\ GslHybridRootFinder.cpp\
GslMinimizer.cpp \
GslQagsIntegrator.cpp \ GslQagsIntegrator.cpp \
Hdf5File.cpp \
Histogram.cpp \ Histogram.cpp \
includes.hpp \ includes.hpp \
Io.cpp \ Io.cpp \
@ -37,14 +41,12 @@ libLatAnalyze_la_SOURCES = \
Math.cpp \ Math.cpp \
MathInterpreter.cpp \ MathInterpreter.cpp \
MathParser.ypp \ MathParser.ypp \
MathLexer.lpp \
MatSample.cpp \
Minimizer.cpp \ Minimizer.cpp \
Model.cpp \ Model.cpp \
Plot.cpp \ Plot.cpp \
RandGen.cpp \
RootFinder.cpp \ RootFinder.cpp \
Solver.cpp \ Solver.cpp \
StatArray.cpp \
TabFunction.cpp \ TabFunction.cpp \
XYSampleData.cpp \ XYSampleData.cpp \
XYStatData.cpp \ XYStatData.cpp \
@ -52,19 +54,18 @@ libLatAnalyze_la_SOURCES = \
libLatAnalyze_ladir = $(pkgincludedir) libLatAnalyze_ladir = $(pkgincludedir)
libLatAnalyze_la_HEADERS = \ libLatAnalyze_la_HEADERS = \
AsciiFile.hpp \ AsciiFile.hpp \
Chi2Function.hpp \
CompiledFunction.hpp \ CompiledFunction.hpp \
CompiledModel.hpp \ CompiledModel.hpp \
Dataset.hpp \ Dataset.hpp \
Derivative.hpp \ Derivative.hpp \
Exceptions.hpp \ Exceptions.hpp \
FitInterface.hpp \
Function.hpp \ Function.hpp \
File.hpp \ File.hpp \
FitInterface.hpp \
Global.hpp \ Global.hpp \
GslHybridRootFinder.hpp\ GslHybridRootFinder.hpp\
GslMinimizer.hpp \
GslQagsIntegrator.hpp \ GslQagsIntegrator.hpp \
Hdf5File.hpp \
Histogram.hpp \ Histogram.hpp \
Integrator.hpp \ Integrator.hpp \
Io.hpp \ Io.hpp \
@ -77,17 +78,43 @@ libLatAnalyze_la_HEADERS = \
Model.hpp \ Model.hpp \
ParserState.hpp \ ParserState.hpp \
Plot.hpp \ Plot.hpp \
RandGen.hpp \
RootFinder.hpp \ RootFinder.hpp \
TabFunction.hpp \ TabFunction.hpp \
Solver.hpp \ Solver.hpp \
StatArray.hpp \ StatArray.hpp \
XYSampleData.hpp \ XYSampleData.hpp \
XYStatData.hpp XYStatData.hpp
if HAVE_HDF5
libLatAnalyze_la_SOURCES += Hdf5File.cpp
libLatAnalyze_la_HEADERS += Hdf5File.hpp
endif
if HAVE_MINUIT if HAVE_MINUIT
libLatAnalyze_la_SOURCES += MinuitMinimizer.cpp libLatAnalyze_la_SOURCES += MinuitMinimizer.cpp
libLatAnalyze_la_HEADERS += MinuitMinimizer.hpp libLatAnalyze_la_HEADERS += MinuitMinimizer.hpp
endif endif
if HAVE_NLOPT
libLatAnalyze_la_SOURCES += NloptMinimizer.cpp
libLatAnalyze_la_HEADERS += NloptMinimizer.hpp
endif
libLatAnalyze_la_CXXFLAGS = $(COM_CXXFLAGS) libLatAnalyze_la_CXXFLAGS = $(COM_CXXFLAGS)
libLatAnalyze_la_LIBADD = libLexers.la
if HAVE_AM_MINOR_LE_11
AsciiParser.hpp: AsciiParser.ypp
$(AM_V_YACC) $(YACC) -o AsciiParser.cpp --defines=AsciiParser.hpp $<
MathParser.hpp: MathParser.ypp
$(AM_V_YACC) $(YACC) -o MathParser.cpp --defines=MathParser.hpp $<
endif
BUILT_SOURCES = AsciiParser.hpp MathParser.hpp
CLEANFILES = \
MathLexer.cpp \
AsciiLexer.cpp \
AsciiParser.cpp\
AsciiParser.hpp\
MathParser.cpp \
MathParser.hpp
ACLOCAL_AMFLAGS = -I .buildutils/m4 ACLOCAL_AMFLAGS = -I .buildutils/m4

View File

@ -1,7 +1,7 @@
/* /*
* Mat.cpp, part of LatAnalyze 3 * Mat.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
* Mat.hpp, part of LatAnalyze 3 * Mat.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
* MatSample.hpp, part of LatAnalyze 3 * MatSample.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -23,7 +23,6 @@
#include <LatAnalyze/Global.hpp> #include <LatAnalyze/Global.hpp>
#include <LatAnalyze/Mat.hpp> #include <LatAnalyze/Mat.hpp>
#include <LatAnalyze/StatArray.hpp> #include <LatAnalyze/StatArray.hpp>
#include <functional>
BEGIN_LATAN_NAMESPACE BEGIN_LATAN_NAMESPACE
@ -35,7 +34,7 @@ BEGIN_LATAN_NAMESPACE
std::placeholders::_1, x)) std::placeholders::_1, x))
template <typename T> template <typename T>
class MatSample: public Sample<Mat<T>>, public IoObject class MatSample: public Sample<Mat<T>>
{ {
public: public:
// block type template // block type template
@ -104,9 +103,6 @@ public:
const Index nCol); const Index nCol);
// resize all matrices // resize all matrices
void resizeMat(const Index nRow, const Index nCol); void resizeMat(const Index nRow, const Index nCol);
// IO type
virtual IoType getType(void) const;
}; };
// non-member operators // non-member operators
@ -383,12 +379,6 @@ void MatSample<T>::resizeMat(const Index nRow, const Index nCol)
} }
} }
// IO type /////////////////////////////////////////////////////////////////////
template <typename T>
IoObject::IoType MatSample<T>::getType(void) const
{
return IoType::noType;
}
END_LATAN_NAMESPACE END_LATAN_NAMESPACE

View File

@ -1,7 +1,7 @@
/* /*
* Math.cpp, part of LatAnalyze 3 * Math.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -24,6 +24,19 @@
using namespace std; using namespace std;
using namespace Latan; using namespace Latan;
/******************************************************************************
* Custom math functions *
******************************************************************************/
DMat MATH_NAMESPACE::varToCorr(const DMat &var)
{
DMat res = var, invDiag = res.diagonal();
invDiag = invDiag.cwiseInverse().cwiseSqrt();
res = (invDiag*invDiag.transpose()).cwiseProduct(res);
return res;
}
/****************************************************************************** /******************************************************************************
* Standard C functions * * Standard C functions *
******************************************************************************/ ******************************************************************************/

View File

@ -1,7 +1,7 @@
/* /*
* Math.hpp, part of LatAnalyze 3 * Math.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -68,6 +68,9 @@ namespace MATH_NAMESPACE
return res; return res;
} }
// convert variance matrix to correlation matrix
DMat varToCorr(const DMat &var);
// Constants // Constants
const double pi = 3.1415926535897932384626433832795028841970; const double pi = 3.1415926535897932384626433832795028841970;
const double e = 2.7182818284590452353602874713526624977572; const double e = 2.7182818284590452353602874713526624977572;

View File

@ -1,7 +1,7 @@
/* /*
* MathInterpreter.cpp, part of LatAnalyze 3 * MathInterpreter.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -411,7 +411,7 @@ void ExprNode::pushArg(ExprNode *node)
// ExprNode operators ////////////////////////////////////////////////////////// // ExprNode operators //////////////////////////////////////////////////////////
const ExprNode &ExprNode::operator[](const Index i) const const ExprNode &ExprNode::operator[](const Index i) const
{ {
return *arg_[static_cast<unsigned int>(i)]; return *arg_[i];
} }
ostream &Latan::operator<<(ostream &out, const ExprNode &n) ostream &Latan::operator<<(ostream &out, const ExprNode &n)
@ -451,7 +451,7 @@ try\
}\ }\
catch (out_of_range)\ catch (out_of_range)\
{\ {\
address = static_cast<unsigned int>((table).size());\ address = (table).size();\
(table)[(name)] = address;\ (table)[(name)] = address;\
}\ }\
@ -582,7 +582,7 @@ MathInterpreter::MathInterpreter(const std::string &code)
// access ////////////////////////////////////////////////////////////////////// // access //////////////////////////////////////////////////////////////////////
const Instruction * MathInterpreter::operator[](const Index i) const const Instruction * MathInterpreter::operator[](const Index i) const
{ {
return program_[static_cast<unsigned int>(i)].get(); return program_[i].get();
} }
const ExprNode * MathInterpreter::getAST(void) const const ExprNode * MathInterpreter::getAST(void) const

View File

@ -1,7 +1,7 @@
/* /*
* MathInterpreter.hpp, part of LatAnalyze 3 * MathInterpreter.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -20,11 +20,6 @@
#ifndef Latan_MathInterpreter_hpp_ #ifndef Latan_MathInterpreter_hpp_
#define Latan_MathInterpreter_hpp_ #define Latan_MathInterpreter_hpp_
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <stack>
#include <LatAnalyze/Function.hpp> #include <LatAnalyze/Function.hpp>
#include <LatAnalyze/Global.hpp> #include <LatAnalyze/Global.hpp>
#include <LatAnalyze/ParserState.hpp> #include <LatAnalyze/ParserState.hpp>

View File

@ -1,7 +1,7 @@
/* /*
* MathLexer.lpp, part of LatAnalyze 3 * MathLexer.lpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -25,20 +25,9 @@
%option yylineno %option yylineno
%{ %{
#include <iostream>
#include <LatAnalyze/MathInterpreter.hpp> #include <LatAnalyze/MathInterpreter.hpp>
#include "MathParser.hpp" #include "MathParser.hpp"
#if (defined __INTEL_COMPILER)
#pragma warning disable 1682 2259
#elif (defined __GNUC__)||(defined __clang__)
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
using namespace std; using namespace std;
using namespace Latan; using namespace Latan;

View File

@ -1,7 +1,7 @@
/* /*
* MathParser.ypp, part of LatAnalyze 3 * MathParser.ypp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -18,25 +18,15 @@
*/ */
%{ %{
#include <iostream>
#include <sstream>
#include <cstring>
#include <LatAnalyze/Global.hpp> #include <LatAnalyze/Global.hpp>
#include <LatAnalyze/MathInterpreter.hpp> #include <LatAnalyze/MathInterpreter.hpp>
#if (defined __INTEL_COMPILER)
#pragma warning disable 1682 2259
#elif (defined __GNUC__)||(defined __clang__)
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
using namespace std; using namespace std;
using namespace Latan; using namespace Latan;
%} %}
%pure-parser %pure-parser
%name-prefix = "_math_" %name-prefix "_math_"
%locations %locations
%defines %defines
%error-verbose %error-verbose

View File

@ -1,7 +1,7 @@
/* /*
* Minimizer.cpp, part of LatAnalyze 3 * Minimizer.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -23,12 +23,6 @@
using namespace std; using namespace std;
using namespace Latan; using namespace Latan;
// constructor /////////////////////////////////////////////////////////////////
Minimizer::Minimizer(const Index dim)
{
resize(dim);
}
// access ////////////////////////////////////////////////////////////////////// // access //////////////////////////////////////////////////////////////////////
void Minimizer::resize(const Index dim) void Minimizer::resize(const Index dim)
{ {
@ -49,119 +43,152 @@ void Minimizer::resize(const Index dim)
} }
} }
// limits ////////////////////////////////////////////////////////////////////// #define checkSupport \
if (!supportLimits())\
{\
LATAN_ERROR(Implementation, "minimizer does not support limits");\
}
double Minimizer::getHighLimit(const Index i) const double Minimizer::getHighLimit(const Index i) const
{ {
checkSupport;
if (i >= getDim())
{
LATAN_ERROR(Size, "invalid variable index");
}
return highLimit_(i); return highLimit_(i);
} }
const DVec & Minimizer::getHighLimit(const PlaceHolder ph __dumb) const const DVec & Minimizer::getHighLimit(const PlaceHolder ph __dumb) const
{ {
checkSupport;
return highLimit_; return highLimit_;
} }
double Minimizer::getLowLimit(const Index i) const double Minimizer::getLowLimit(const Index i) const
{ {
checkSupport;
if (i >= getDim())
{
LATAN_ERROR(Size, "invalid variable index");
}
return lowLimit_(i); return lowLimit_(i);
} }
const DVec & Minimizer::getLowLimit(const PlaceHolder ph __dumb) const const DVec & Minimizer::getLowLimit(const PlaceHolder ph __dumb) const
{ {
checkSupport;
return lowLimit_; return lowLimit_;
} }
bool Minimizer::hasHighLimit(const Index i) const bool Minimizer::hasHighLimit(const Index i) const
{ {
checkSupport;
if (i >= getDim())
{
LATAN_ERROR(Size, "invalid variable index");
}
return hasHighLimit_(i); return hasHighLimit_(i);
} }
bool Minimizer::hasLowLimit(const Index i) const bool Minimizer::hasLowLimit(const Index i) const
{ {
checkSupport;
if (i >= getDim())
{
LATAN_ERROR(Size, "invalid variable index");
}
return hasLowLimit_(i); return hasLowLimit_(i);
} }
void Minimizer::setHighLimit(const Index i, const double l) void Minimizer::setHighLimit(const Index i, const double l)
{ {
checkSupport;
if (i >= getDim()) if (i >= getDim())
{ {
LATAN_ERROR(Size, "invalid limit index"); resize(i + 1);
}
else
{
highLimit_(i) = l;
useHighLimit(i);
} }
highLimit_(i) = l;
useHighLimit(i);
} }
void Minimizer::setHighLimit(const PlaceHolder ph __dumb, const DVec &l) void Minimizer::setHighLimit(const PlaceHolder ph __dumb, const DVec &l)
{ {
checkSupport;
if (l.size() != getDim()) if (l.size() != getDim())
{ {
LATAN_ERROR(Size, "invalid limit vector size"); resize(l.size());
}
else
{
highLimit_ = l;
useHighLimit(_);
} }
highLimit_ = l;
useHighLimit(_);
} }
void Minimizer::setLowLimit(const Index i, const double l) void Minimizer::setLowLimit(const Index i, const double l)
{ {
checkSupport;
if (i >= getDim()) if (i >= getDim())
{ {
LATAN_ERROR(Size, "invalid limit index"); resize(i + 1);
}
else
{
lowLimit_(i) = l;
useLowLimit(i);
} }
lowLimit_(i) = l;
useLowLimit(i);
} }
void Minimizer::setLowLimit(const PlaceHolder ph __dumb, const DVec &l) void Minimizer::setLowLimit(const PlaceHolder ph __dumb, const DVec &l)
{ {
checkSupport;
if (l.size() != getDim()) if (l.size() != getDim())
{ {
LATAN_ERROR(Size, "invalid limit vector size"); resize(l.size());
}
else
{
lowLimit_ = l;
useLowLimit(_);
} }
lowLimit_ = l;
useLowLimit(_);
} }
void Minimizer::useHighLimit(const Index i, const bool use) void Minimizer::useHighLimit(const Index i, const bool use)
{ {
checkSupport;
if (i >= getDim()) if (i >= getDim())
{ {
LATAN_ERROR(Size, "invalid limit index"); resize(i + 1);
}
else
{
hasHighLimit_(i) = use;
} }
hasHighLimit_(i) = use;
} }
void Minimizer::useHighLimit(const PlaceHolder ph __dumb, const bool use) void Minimizer::useHighLimit(const PlaceHolder ph __dumb, const bool use)
{ {
checkSupport;
hasHighLimit_.fill(use); hasHighLimit_.fill(use);
} }
void Minimizer::useLowLimit(const Index i, const bool use) void Minimizer::useLowLimit(const Index i, const bool use)
{ {
checkSupport;
if (i >= getDim()) if (i >= getDim())
{ {
LATAN_ERROR(Size, "invalid limit index"); resize(i + 1);
}
else
{
hasLowLimit_(i) = use;
} }
hasLowLimit_(i) = use;
} }
void Minimizer::useLowLimit(const PlaceHolder ph __dumb, const bool use) void Minimizer::useLowLimit(const PlaceHolder ph __dumb, const bool use)
{ {
checkSupport;
hasLowLimit_.fill(use); hasLowLimit_.fill(use);
} }
unsigned int Minimizer::getMaxPass(void) const
{
return maxPass_;
}
void Minimizer::setMaxPass(const unsigned int maxPass)
{
maxPass_ = maxPass;
}

View File

@ -1,7 +1,7 @@
/* /*
* Minimizer.hpp, part of LatAnalyze 3 * Minimizer.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -36,12 +36,10 @@ class Minimizer: public Solver
public: public:
// constructor // constructor
Minimizer(void) = default; Minimizer(void) = default;
explicit Minimizer(const Index dim);
// destructor // destructor
virtual ~Minimizer(void) = default; virtual ~Minimizer(void) = default;
// access // access
virtual void resize(const Index dim); virtual void resize(const Index dim);
// limits
virtual double getHighLimit(const Index i) const ; virtual double getHighLimit(const Index i) const ;
virtual const DVec & getHighLimit(const PlaceHolder ph = _) const; virtual const DVec & getHighLimit(const PlaceHolder ph = _) const;
virtual double getLowLimit(const Index i) const; virtual double getLowLimit(const Index i) const;
@ -58,11 +56,15 @@ public:
virtual void useLowLimit(const Index i, const bool use = true); virtual void useLowLimit(const Index i, const bool use = true);
virtual void useLowLimit(const PlaceHolder ph = _, virtual void useLowLimit(const PlaceHolder ph = _,
const bool use = true); const bool use = true);
virtual bool supportLimits(void) const = 0;
virtual unsigned int getMaxPass(void) const;
virtual void setMaxPass(const unsigned int maxPass);
// minimization // minimization
virtual const DVec & operator()(const DoubleFunction &f) = 0; virtual const DVec & operator()(const DoubleFunction &f) = 0;
private: private:
DVec highLimit_, lowLimit_; DVec highLimit_, lowLimit_;
Vec<bool> hasHighLimit_, hasLowLimit_; Vec<bool> hasHighLimit_, hasLowLimit_;
unsigned int maxPass_{5u};
}; };
END_LATAN_NAMESPACE END_LATAN_NAMESPACE

View File

@ -1,7 +1,7 @@
/* /*
* MinuitMinimizer.cpp, part of LatAnalyze 3 * MinuitMinimizer.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -19,186 +19,158 @@
#include <LatAnalyze/MinuitMinimizer.hpp> #include <LatAnalyze/MinuitMinimizer.hpp>
#include <LatAnalyze/includes.hpp> #include <LatAnalyze/includes.hpp>
#include <Minuit2/Minuit2Minimizer.h>
#pragma GCC diagnostic ignored "-Wconversion" #include <Math/Functor.h>
#include <Minuit2/FCNBase.h>
#include <Minuit2/FunctionMinimum.h>
#include <Minuit2/MnMigrad.h>
#include <Minuit2/MnPrint.h>
#include <Minuit2/MnPlot.h>
#include <Minuit2/MnScan.h>
#include <Minuit2/MnSimplex.h>
#include <Minuit2/ScanMinimizer.h>
#include <Minuit2/SimplexMinimizer.h>
#include <Minuit2/VariableMetricMinimizer.h>
using namespace std; using namespace std;
using namespace ROOT;
using namespace Minuit2;
using namespace Latan; using namespace Latan;
static constexpr double initErr = 0.5; static constexpr double initErr = 0.1;
static constexpr unsigned int maxTry = 10u;
/****************************************************************************** /******************************************************************************
* MinuitMinimizer implementation * * MinuitMinimizer implementation *
******************************************************************************/ ******************************************************************************/
// MinuitFunction constructor //////////////////////////////////////////////////
MinuitMinimizer::MinuitFunction::MinuitFunction(const DoubleFunction &f)
: f_(&f)
{}
// MinuitFunction minuit members ///////////////////////////////////////////////
double MinuitMinimizer::MinuitFunction::operator()
(const vector<double> &x) const
{
return (*f_)(x);
}
double MinuitMinimizer::MinuitFunction::Up(void) const
{
return 1.;
}
// constructors //////////////////////////////////////////////////////////////// // constructors ////////////////////////////////////////////////////////////////
MinuitMinimizer::MinuitMinimizer(const Algorithm algorithm) MinuitMinimizer::MinuitMinimizer(const Algorithm algorithm)
{ {
setAlgorithm(algorithm); setAlgorithm(algorithm);
} }
MinuitMinimizer::MinuitMinimizer(const Index dim, const Algorithm algorithm)
: Minimizer(dim)
{
setAlgorithm(algorithm);
}
// access ////////////////////////////////////////////////////////////////////// // access //////////////////////////////////////////////////////////////////////
MinuitMinimizer::Algorithm MinuitMinimizer::getAlgorithm(void) const MinuitMinimizer::Algorithm MinuitMinimizer::getAlgorithm(void) const
{ {
return algorithm_; return algorithm_;
} }
double MinuitMinimizer::getPrecision(void) const
{
LATAN_ERROR(Implementation,
"Minuit minimizer precision cannot be accessed");
return 0.;
}
void MinuitMinimizer::setAlgorithm(const Algorithm algorithm) void MinuitMinimizer::setAlgorithm(const Algorithm algorithm)
{ {
algorithm_ = algorithm; algorithm_ = algorithm;
} }
void MinuitMinimizer::setPrecision(const double precision __dumb) bool MinuitMinimizer::supportLimits(void) const
{ {
LATAN_ERROR(Implementation, return true;
"Minuit minimizer precision cannot be accessed");
} }
// minimization //////////////////////////////////////////////////////////////// // minimization ////////////////////////////////////////////////////////////////
const DVec & MinuitMinimizer::operator()(const DoubleFunction &f) const DVec & MinuitMinimizer::operator()(const DoubleFunction &f)
{ {
DVec &x = getState(); using namespace ROOT;
Verbosity verbosity = getVerbosity(); using namespace Minuit2;
DVec &x = getState();
int printLevel = 0;
EMinimizerType minuitAlg = kCombined;
// convert Latan parameters to Minuit parameters
switch (getVerbosity())
{
case Verbosity::Silent:
printLevel = 0;
break;
case Verbosity::Normal:
printLevel = 2;
break;
case Verbosity::Debug:
printLevel = 3;
break;
}
switch (getAlgorithm())
{
case Algorithm::migrad:
minuitAlg = kMigrad;
break;
case Algorithm::simplex:
minuitAlg = kSimplex;
break;
case Algorithm::combined:
minuitAlg = kCombined;
break;
}
// resize minimizer state to match function number of arguments
if (f.getNArg() != x.size()) if (f.getNArg() != x.size())
{ {
resize(f.getNArg()); resize(f.getNArg());
} }
// set parameters // create and set minimizer
MinuitFunction minuitF(f); Minuit2Minimizer min(minuitAlg);
MnUserParameters parameters;
min.SetStrategy(2);
min.SetMaxFunctionCalls(getMaxIteration());
min.SetTolerance(getPrecision());
min.SetPrintLevel(printLevel);
// set function and variables
Math::Functor minuitF(f, x.size());
string name;
double val, step;
min.SetFunction(minuitF);
for (Index i = 0; i < x.size(); ++i) for (Index i = 0; i < x.size(); ++i)
{ {
parameters.Add("x_" + strFrom(i), x(i), initErr*fabs(x(i))); name = f.varName().getName(i);
if (hasLowLimit(i)&&hasHighLimit(i)) val = x(i);
step = (fabs(x(i)) != 0.) ? initErr*fabs(x(i)) : 1.;
if (hasHighLimit(i) and !hasLowLimit(i))
{ {
parameters.SetLimits(static_cast<unsigned int>(i), min.SetUpperLimitedVariable(i, name, val, step, getHighLimit(i));
getLowLimit(i), getHighLimit(i));
} }
else if (hasLowLimit(i)) else if (!hasHighLimit(i) and hasLowLimit(i))
{ {
parameters.SetLowerLimit(static_cast<unsigned int>(i), min.SetLowerLimitedVariable(i, name, val, step, getLowLimit(i));
getLowLimit(i));
} }
else if (hasHighLimit(i)) else if (hasHighLimit(i) and hasLowLimit(i))
{ {
parameters.SetUpperLimit(static_cast<unsigned int>(i), min.SetLimitedVariable(i, name, val, step, getLowLimit(i),
getHighLimit(i)); getHighLimit(i));
}
else
{
min.SetVariable(i, name, val, step);
} }
} }
// pre-minimization // minimize
MnSimplex preMinimizer(minuitF, parameters, 1); int status;
FunctionMinimum preMin = preMinimizer(); unsigned int n = 0;
if (verbosity >= Verbosity::Debug) do
{ {
cout << "-- MINUIT pre-minimization -----------------------------"; if (getVerbosity() >= Verbosity::Normal)
cout << preMin;
cout << "--------------------------------------------------------";
cout << endl;
}
for (unsigned int i = 0; i < x.size(); ++i)
{
parameters.SetValue(i, preMin.UserParameters().Value(i));
parameters.SetError(i, 2.*preMin.UserParameters().Error(i));
}
// minimization and output
unique_ptr<MnApplication> minimizer(nullptr);
if (algorithm_ == Algorithm::Migrad)
{
minimizer.reset(new MnMigrad(minuitF, parameters, 2));
}
else if (algorithm_ == Algorithm::Simplex)
{
minimizer.reset(new MnSimplex(minuitF, parameters, 2));
}
unsigned int iTry = 0;
FunctionMinimum min = (*minimizer)();
while ((!min.IsValid())&&(iTry < maxTry))
{
min = (*minimizer)();
iTry++;
}
if (!min.IsValid())
{
LATAN_WARNING("MINUIT library reported that minimization result is not valid");
}
for (unsigned int i = 0; i < x.size(); ++i)
{
x(i) = min.UserParameters().Value(i);
}
if (verbosity >= Verbosity::Normal)
{
cout << "-- MINUIT minimization ---------------------------------";
cout << min;
cout << "--------------------------------------------------------";
cout << endl;
}
if (verbosity >= Verbosity::Debug)
{
vector<pair<double, double>> scanRes;
MnPlot plot;
MnScan scanner(minuitF, preMin.UserParameters(), 2);
cout << "-- MINUIT scan -----------------------------------------";
cout << endl;
for (unsigned int i = 0; i < x.size(); i++)
{ {
cout << "Parameter x_" << i << endl; cout << "========== Minuit minimization, pass #" << n + 1;
scanRes = scanner.Scan(i); cout << " =========" << endl;
plot(scanRes);
} }
cout << "--------------------------------------------------------"; min.Minimize();
cout << endl; status = min.Status();
n++;
} while (status and (n < getMaxPass()));
if (getVerbosity() >= Verbosity::Normal)
{
cout << "=================================================" << endl;
}
switch (status)
{
case 1:
LATAN_WARNING("invalid minimum: covariance matrix was made positive");
break;
case 2:
LATAN_WARNING("invalid minimum: Hesse analysis is not valid");
break;
case 3:
LATAN_WARNING("invalid minimum: requested precision not reached");
break;
case 4:
LATAN_WARNING("invalid minimum: iteration limit reached");
break;
}
// save and return result
for (Index i = 0; i < x.size(); ++i)
{
x(i) = min.X()[i];
} }
return x; return x;

View File

@ -1,7 +1,7 @@
/* /*
* MinuitMinimizer.hpp, part of LatAnalyze 3 * MinuitMinimizer.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -23,52 +23,36 @@
#include <LatAnalyze/Global.hpp> #include <LatAnalyze/Global.hpp>
#include <LatAnalyze/Function.hpp> #include <LatAnalyze/Function.hpp>
#include <LatAnalyze/Minimizer.hpp> #include <LatAnalyze/Minimizer.hpp>
#include <Minuit2/FCNBase.h>
BEGIN_LATAN_NAMESPACE BEGIN_LATAN_NAMESPACE
/****************************************************************************** /******************************************************************************
* Minuit minimizer * * interface to CERN Minuit minimizer *
* ( http://www.cern.ch/minuit ) *
******************************************************************************/ ******************************************************************************/
class MinuitMinimizer: public Minimizer class MinuitMinimizer: public Minimizer
{ {
public: public:
enum class Algorithm enum class Algorithm
{ {
Migrad = 1, migrad = 1,
Simplex = 2 simplex = 2,
}; combined = 3
private:
class MinuitFunction: public ROOT::Minuit2::FCNBase
{
public:
// constructor
explicit MinuitFunction(const DoubleFunction &f);
// destructor
virtual ~MinuitFunction(void) = default;
// minuit members
virtual double operator()(const std::vector<double> &x) const;
virtual double Up(void) const;
private:
const DoubleFunction *f_;
}; };
public: public:
// constructors // constructor
MinuitMinimizer(const Algorithm algorithm = Algorithm::Migrad); explicit MinuitMinimizer(const Algorithm algorithm = defaultAlg_);
explicit MinuitMinimizer(const Index dim,
const Algorithm algorithm = Algorithm::Migrad);
// destructor // destructor
virtual ~MinuitMinimizer(void) = default; virtual ~MinuitMinimizer(void) = default;
// access // access
virtual double getPrecision(void) const; Algorithm getAlgorithm(void) const;
Algorithm getAlgorithm(void) const; void setAlgorithm(const Algorithm algorithm);
virtual void setPrecision(const double precision); virtual bool supportLimits(void) const;
void setAlgorithm(const Algorithm algorithm);
// minimization // minimization
virtual const DVec & operator()(const DoubleFunction &f); virtual const DVec & operator()(const DoubleFunction &f);
private: private:
Algorithm algorithm_; Algorithm algorithm_;
static constexpr Algorithm defaultAlg_ = Algorithm::combined;
}; };
END_LATAN_NAMESPACE END_LATAN_NAMESPACE

View File

@ -1,7 +1,7 @@
/* /*
* Model.cpp, part of LatAnalyze 3 * Model.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -19,7 +19,6 @@
#include <LatAnalyze/Model.hpp> #include <LatAnalyze/Model.hpp>
#include <LatAnalyze/includes.hpp> #include <LatAnalyze/includes.hpp>
#include <functional>
using namespace std; using namespace std;
using namespace std::placeholders; using namespace std::placeholders;
@ -31,6 +30,8 @@ using namespace Latan;
// constructor ///////////////////////////////////////////////////////////////// // constructor /////////////////////////////////////////////////////////////////
DoubleModel::DoubleModel(const vecFunc &f, const Index nArg, const Index nPar) DoubleModel::DoubleModel(const vecFunc &f, const Index nArg, const Index nPar)
: size_(new ModelSize) : size_(new ModelSize)
, varName_("x")
, parName_("p")
{ {
setFunction(f, nArg, nPar); setFunction(f, nArg, nPar);
} }
@ -54,6 +55,26 @@ void DoubleModel::setFunction(const vecFunc &f, const Index nArg,
f_ = f; f_ = f;
} }
VarName & DoubleModel::varName(void)
{
return varName_;
}
const VarName & DoubleModel::varName(void) const
{
return varName_;
}
VarName & DoubleModel::parName(void)
{
return parName_;
}
const VarName & DoubleModel::parName(void) const
{
return parName_;
}
// error checking ////////////////////////////////////////////////////////////// // error checking //////////////////////////////////////////////////////////////
void DoubleModel::checkSize(const Index nArg, const Index nPar) const void DoubleModel::checkSize(const Index nArg, const Index nPar) const
{ {

View File

@ -1,7 +1,7 @@
/* /*
* Model.hpp, part of LatAnalyze 3 * Model.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -23,7 +23,6 @@
#include <LatAnalyze/Global.hpp> #include <LatAnalyze/Global.hpp>
#include <LatAnalyze/Function.hpp> #include <LatAnalyze/Function.hpp>
#include <LatAnalyze/Mat.hpp> #include <LatAnalyze/Mat.hpp>
#include <vector>
BEGIN_LATAN_NAMESPACE BEGIN_LATAN_NAMESPACE
@ -43,10 +42,14 @@ public:
// destructor // destructor
virtual ~DoubleModel(void) = default; virtual ~DoubleModel(void) = default;
// access // access
virtual Index getNArg(void) const; virtual Index getNArg(void) const;
virtual Index getNPar(void) const; virtual Index getNPar(void) const;
void setFunction(const vecFunc &f, const Index nArg, void setFunction(const vecFunc &f, const Index nArg,
const Index nPar); const Index nPar);
VarName & varName(void);
const VarName & varName(void) const;
VarName & parName(void);
const VarName & parName(void) const;
// function call // function call
double operator()(const DVec &data, const DVec &par) const; double operator()(const DVec &data, const DVec &par) const;
double operator()(const std::vector<double> &data, double operator()(const std::vector<double> &data,
@ -61,6 +64,7 @@ private:
void checkSize(const Index nArg, const Index nPar) const; void checkSize(const Index nArg, const Index nPar) const;
private: private:
std::shared_ptr<ModelSize> size_; std::shared_ptr<ModelSize> size_;
VarName varName_, parName_;
vecFunc f_; vecFunc f_;
}; };

201
lib/NloptMinimizer.cpp Normal file
View File

@ -0,0 +1,201 @@
/*
* NloptMinimizer.cpp, part of LatAnalyze 3
*
* Copyright (C) 2013 - 2016 Antonin Portelli
*
* LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LatAnalyze 3 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
*/
#include <LatAnalyze/NloptMinimizer.hpp>
#include <LatAnalyze/includes.hpp>
using namespace std;
using namespace Latan;
/******************************************************************************
* NloptMinimizer implementation *
******************************************************************************/
// constructors ////////////////////////////////////////////////////////////////
NloptMinimizer::NloptMinimizer(const Algorithm algorithm)
{
setAlgorithm(algorithm);
der_.setOrder(1, 1);
}
// access //////////////////////////////////////////////////////////////////////
NloptMinimizer::Algorithm NloptMinimizer::getAlgorithm(void) const
{
return algorithm_;
}
void NloptMinimizer::setAlgorithm(const Algorithm algorithm)
{
algorithm_ = algorithm;
}
bool NloptMinimizer::supportLimits(void) const
{
return true;
}
// minimization ////////////////////////////////////////////////////////////////
const DVec & NloptMinimizer::operator()(const DoubleFunction &f)
{
DVec &x = getState();
// resize minimizer state to match function number of arguments
if (f.getNArg() != x.size())
{
resize(f.getNArg());
}
// create and set minimizer
nlopt::opt min(getAlgorithm(), x.size());
NloptFuncData data;
vector<double> lb(x.size()), hb(x.size());
min.set_maxeval(getMaxIteration());
min.set_xtol_rel(getPrecision());
min.set_ftol_rel(-1.);
der_.setFunction(f);
data.f = &f;
data.d = &der_;
min.set_min_objective(&funcWrapper, &data);
for (Index i = 0; i < x.size(); ++i)
{
lb[i] = hasLowLimit(i) ? getLowLimit(i) : -HUGE_VAL;
hb[i] = hasHighLimit(i) ? getHighLimit(i) : HUGE_VAL;
}
min.set_lower_bounds(lb);
min.set_upper_bounds(hb);
// minimize
double res;
vector<double> vx(x.size());
nlopt::result status;
unsigned int n = 0;
for (Index i = 0; i < x.size(); ++i)
{
vx[i] = x(i);
}
do
{
if (getVerbosity() >= Verbosity::Normal)
{
cout << "========== NLopt minimization, pass #" << n + 1;
cout << " ==========" << endl;
cout << "Algorithm: " << min.get_algorithm_name() << endl;
cout << "Max eval.= " << min.get_maxeval();
cout << " -- Precision= " << min.get_xtol_rel() << endl;
printf("Starting f(x)= %.10e\n", f(x));
}
try
{
status = min.optimize(vx, res);
}
catch (invalid_argument &e)
{
LATAN_ERROR(Runtime, "NLopt has reported receving invalid "
"arguments (if you are using a global minimizer, did "
"you specify limits for all variables?)");
}
if (getVerbosity() >= Verbosity::Normal)
{
printf("Found minimum %.10e at:\n", res);
for (Index i = 0; i < x.size(); ++i)
{
printf("%8s= %.10e\n", f.varName().getName(i).c_str(), vx[i]);
}
cout << "after " << data.evalCount << " evaluations" << endl;
cout << "Minimization ended with code " << status;
cout << " (" << returnMessage(status) << ")";
cout << endl;
}
data.evalCount = 0;
for (Index i = 0; i < x.size(); ++i)
{
x(i) = vx[i];
}
n++;
} while (!minSuccess(status) and (n < getMaxPass()));
if (getVerbosity() >= Verbosity::Normal)
{
cout << "=================================================" << endl;
}
if (!minSuccess(status))
{
LATAN_WARNING("invalid minimum: " + returnMessage(status));
}
return x;
}
// NLopt return code parser ////////////////////////////////////////////////////
string NloptMinimizer::returnMessage(const nlopt::result status)
{
switch (status)
{
case nlopt::SUCCESS:
return "success";
case nlopt::STOPVAL_REACHED:
return "stopping value reached";
case nlopt::FTOL_REACHED:
return "tolerance on function reached";
case nlopt::XTOL_REACHED:
return "tolerance on variable reached";
case nlopt::MAXEVAL_REACHED:
return "maximum function evaluation reached";
case nlopt::MAXTIME_REACHED:
return "maximum time reached";
default:
return "";
}
}
// NLopt function wrapper //////////////////////////////////////////////////////
double NloptMinimizer::funcWrapper(unsigned int n, const double *arg,
double *grad , void *vdata)
{
NloptFuncData &data = *static_cast<NloptFuncData *>(vdata);
if (grad)
{
for (unsigned int i = 0; i < n; ++i)
{
data.d->setDir(i);
grad[i] = (*(data.d))(arg);
}
data.evalCount += data.d->getNPoint()*n;
}
data.evalCount++;
return (*data.f)(arg);
}
// NLopt return status parser //////////////////////////////////////////////////
bool NloptMinimizer::minSuccess(const nlopt::result status)
{
switch (status)
{
case nlopt::SUCCESS:
case nlopt::FTOL_REACHED:
case nlopt::XTOL_REACHED:
return true;
break;
default:
return false;
break;
}
}

76
lib/NloptMinimizer.hpp Normal file
View File

@ -0,0 +1,76 @@
/*
* NloptMinimizer.hpp, part of LatAnalyze 3
*
* Copyright (C) 2013 - 2016 Antonin Portelli
*
* LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LatAnalyze 3 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Latan_NloptMinimizer_hpp_
#define Latan_NloptMinimizer_hpp_
#include <LatAnalyze/Global.hpp>
#include <LatAnalyze/Derivative.hpp>
#include <LatAnalyze/Function.hpp>
#include <LatAnalyze/Minimizer.hpp>
#include <nlopt.hpp>
BEGIN_LATAN_NAMESPACE
/******************************************************************************
* interface to NLOpt minimizers *
* ( http://ab-initio.mit.edu/wiki/index.php/NLopt ) *
* -------------------------------------------------------------------------- *
* cf. http://ab-initio.mit.edu/wiki/index.php/NLopt_Algorithms for algorithm *
* references and naming conventions *
******************************************************************************/
class NloptMinimizer: public Minimizer
{
public:
typedef nlopt::algorithm Algorithm;
private:
struct NloptFuncData
{
const DoubleFunction *f{nullptr};
Derivative *d{nullptr};
unsigned int evalCount{0};
};
public:
// constructor
explicit NloptMinimizer(const Algorithm algorithm = defaultAlg_);
// destructor
virtual ~NloptMinimizer(void) = default;
// access
Algorithm getAlgorithm(void) const;
void setAlgorithm(const Algorithm algorithm);
virtual bool supportLimits(void) const;
// minimization
virtual const DVec & operator()(const DoubleFunction &f);
private:
// NLopt return code parser
static std::string returnMessage(const nlopt::result status);
// NLopt function wrapper
static double funcWrapper(unsigned int n, const double *arg,
double *grad , void *vdata);
// NLopt return status parser
static bool minSuccess(const nlopt::result status);
private:
Algorithm algorithm_;
static constexpr Algorithm defaultAlg_ = Algorithm::LN_NELDERMEAD;
CentralDerivative der_;
};
END_LATAN_NAMESPACE
#endif // Latan_NloptMinimizer_hpp_

View File

@ -1,7 +1,7 @@
/* /*
* ParserState.hpp, part of LatAnalyze 3 * ParserState.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -21,7 +21,6 @@
#define Latan_ParserState_hpp_ #define Latan_ParserState_hpp_
#include <LatAnalyze/Global.hpp> #include <LatAnalyze/Global.hpp>
#include <iostream>
BEGIN_LATAN_NAMESPACE BEGIN_LATAN_NAMESPACE

View File

@ -1,7 +1,7 @@
/* /*
* Plot.cpp, part of LatAnalyze 3 * Plot.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -169,15 +169,10 @@ PlotData::PlotData(const DMatSample &x, const DVec &y)
PlotData::PlotData(const XYStatData &data, const Index i, const Index j) PlotData::PlotData(const XYStatData &data, const Index i, const Index j)
{ {
DMat d(data.getNData(), 4);
string usingCmd, tmpFileName; string usingCmd, tmpFileName;
d.col(0) = data.x(i);
d.col(2) = data.y(j);
d.col(1) = data.xxVar(i, i).diagonal().array().sqrt();
d.col(3) = data.yyVar(j, j).diagonal().array().sqrt();
usingCmd = (data.isXExact(i)) ? "u 1:3:4 w yerr" : "u 1:3:2:4 w xyerr"; usingCmd = (data.isXExact(i)) ? "u 1:3:4 w yerr" : "u 1:3:2:4 w xyerr";
tmpFileName = dumpToTmpFile(d); tmpFileName = dumpToTmpFile(data.getTable(i, j));
pushTmpFile(tmpFileName); pushTmpFile(tmpFileName);
setCommand("'" + tmpFileName + "' " + usingCmd); setCommand("'" + tmpFileName + "' " + usingCmd);
} }
@ -252,6 +247,14 @@ PlotHistogram::PlotHistogram(const Histogram &h)
setCommand("'" + tmpFileName + "' u 1:2 w steps"); setCommand("'" + tmpFileName + "' u 1:2 w steps");
} }
// PlotMatrixNoRange constructor ///////////////////////////////////////////////
PlotMatrixNoRange::PlotMatrixNoRange(const DMat &m)
{
string tmpFileName = dumpToTmpFile(m);
setCommand("'" + tmpFileName + "' matrix w image");
}
/****************************************************************************** /******************************************************************************
* Plot modifiers * * Plot modifiers *
******************************************************************************/ ******************************************************************************/

View File

@ -1,7 +1,7 @@
/* /*
* Plot.hpp, part of LatAnalyze 3 * Plot.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -21,11 +21,11 @@
#define Latan_Plot_hpp_ #define Latan_Plot_hpp_
#include <LatAnalyze/Global.hpp> #include <LatAnalyze/Global.hpp>
#include <LatAnalyze/Function.hpp>
#include <LatAnalyze/Mat.hpp> #include <LatAnalyze/Mat.hpp>
#include <LatAnalyze/MatSample.hpp>
#include <LatAnalyze/Histogram.hpp> #include <LatAnalyze/Histogram.hpp>
#include <LatAnalyze/XYStatData.hpp> #include <LatAnalyze/XYStatData.hpp>
#include <sstream>
#include <vector>
// gnuplot default parameters // gnuplot default parameters
#ifndef GNUPLOT_BIN #ifndef GNUPLOT_BIN
@ -47,11 +47,11 @@ public:
// destructor // destructor
virtual ~PlotObject(void) = default; virtual ~PlotObject(void) = default;
// access // access
std::string popTmpFile(void); std::string popTmpFile(void);
const std::string & getCommand(void) const; const std::string & getCommand(void) const;
const std::string & getHeadCommand(void) const; const std::string & getHeadCommand(void) const;
// test // test
bool gotTmpFile(void) const; bool gotTmpFile(void) const;
protected: protected:
// access // access
void pushTmpFile(const std::string &fileName); void pushTmpFile(const std::string &fileName);
@ -136,6 +136,20 @@ public:
virtual ~PlotHistogram(void) = default; virtual ~PlotHistogram(void) = default;
}; };
class PlotMatrixNoRange: public PlotObject
{
public:
// constructor
PlotMatrixNoRange(const DMat &m);
// destructor
virtual ~PlotMatrixNoRange(void) = default;
};
#define PlotMatrix(m)\
PlotRange(Axis::x, -.5, (m).cols() - .5) <<\
PlotRange(Axis::y, (m).rows() - .5, -.5) <<\
PlotMatrixNoRange(m)
/****************************************************************************** /******************************************************************************
* Plot modifiers * * Plot modifiers *
******************************************************************************/ ******************************************************************************/

View File

@ -1,690 +0,0 @@
/*
* RandGen.cpp, part of LatAnalyze 3
*
* Copyright (C) 2013 - 2015 Antonin Portelli
*
* LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LatAnalyze 3 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
*/
#include <LatAnalyze/RandGen.hpp>
#include <LatAnalyze/includes.hpp>
#pragma GCC diagnostic ignored "-Wfloat-conversion"
#ifndef RLXD_LEVEL
#define RLXD_LEVEL 1
#endif
using namespace std;
using namespace Latan;
/******************************************************************************
* RandGenState implementation *
******************************************************************************/
// IO type ///////////////////////////////////////////////////////////////
IoObject::IoType RandGenState::getType(void) const
{
return IoType::rgState;
}
/******************************************************************************
* RandGen implementation *
******************************************************************************/
// RanLxd implementation ///////////////////////////////////////////////////////
RandGen::RanLxd::RanLxd(void)
{
// avoid a warning in the SSE case
one_bit = 0.0;
}
/****************************************************************************/
/* Copyright (C) 2005 Martin Luescher (GPL)
* This software is distributed under the terms of the GNU General Public
* License (GPL)
*
* Random number generator "ranlxd". See the notes
*
* "User's guide for ranlxs and ranlxd v3.2" (December 2005)
*
* "Algorithms used in ranlux v3.0" (May 2001)
*
* for a detailed description
*
* The functions are
*
* void ranlxd(double r[],int n)
* Computes the next n double-precision random numbers and
* assigns them to the elements r[0],...,r[n-1] of the array r[]
*
* void rlxd_init(int level,int seed)
* Initialization of the generator
*
* int rlxd_size(void)
* Returns the number of integers required to save the state of
* the generator
*
* void rlxd_get(int state[])
* Extracts the current state of the generator and stores the
* information in the array state[N] where N>=rlxd_size()
*
* void rlxd_reset(int state[])
* Resets the generator to the state defined by the array state[N]
*/
#ifdef HAVE_SSE
#define STEP(pi,pj) \
__asm__ __volatile__ ("movaps %4, %%xmm4 \n\t" \
"movaps %%xmm2, %%xmm3 \n\t" \
"subps %2, %%xmm4 \n\t" \
"movaps %%xmm1, %%xmm5 \n\t" \
"cmpps $0x6, %%xmm4, %%xmm2 \n\t" \
"andps %%xmm2, %%xmm5 \n\t" \
"subps %%xmm3, %%xmm4 \n\t" \
"andps %%xmm0, %%xmm2 \n\t" \
"addps %%xmm4, %%xmm5 \n\t" \
"movaps %%xmm5, %0 \n\t" \
"movaps %5, %%xmm6 \n\t" \
"movaps %%xmm2, %%xmm3 \n\t" \
"subps %3, %%xmm6 \n\t" \
"movaps %%xmm1, %%xmm7 \n\t" \
"cmpps $0x6, %%xmm6, %%xmm2 \n\t" \
"andps %%xmm2, %%xmm7 \n\t" \
"subps %%xmm3, %%xmm6 \n\t" \
"andps %%xmm0, %%xmm2 \n\t" \
"addps %%xmm6, %%xmm7 \n\t" \
"movaps %%xmm7, %1" \
: \
"=m" ((*pi).c1), \
"=m" ((*pi).c2) \
: \
"m" ((*pi).c1), \
"m" ((*pi).c2), \
"m" ((*pj).c1), \
"m" ((*pj).c2) \
: \
"xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7")
void RandGen::RanLxd::error(int no) const
{
switch(no)
{
case 1:
LATAN_ERROR(Range, "Bad choice of luxury level (should be 1 or 2)");
break;
case 2:
LATAN_ERROR(Range, "Bad choice of seed (should be between 1 and 2^31-1)");
break;
case 3:
LATAN_ERROR(Runtime, "Undefined state (ranlxd is not initialized)");
break;
case 5:
LATAN_ERROR(Logic, "Unexpected input data");
break;
}
}
void RandGen::RanLxd::update(void)
{
int k,kmax;
rlxd_dble_vec_t *pmin,*pmax,*pi,*pj;
kmax=rlxd_pr;
pmin=&rlxd_x.vec[0];
pmax=pmin+12;
pi=&rlxd_x.vec[ir];
pj=&rlxd_x.vec[jr];
__asm__ __volatile__ ("movaps %0, %%xmm0 \n\t"
"movaps %1, %%xmm1 \n\t"
"movaps %2, %%xmm2"
:
:
"m" (one_bit_sse),
"m" (one_sse),
"m" (carry)
:
"xmm0", "xmm1", "xmm2");
for (k=0;k<kmax;k++)
{
STEP(pi,pj);
pi+=1;
pj+=1;
if (pi==pmax)
pi=pmin;
if (pj==pmax)
pj=pmin;
}
__asm__ __volatile__ ("movaps %%xmm2, %0"
:
"=m" (carry));
ir+=prm;
jr+=prm;
if (ir>=12)
ir-=12;
if (jr>=12)
jr-=12;
is=8*ir;
is_old=is;
}
void RandGen::RanLxd::define_constants(void)
{
int k;
float b;
one_sse.c1=1.0f;
one_sse.c2=1.0f;
one_sse.c3=1.0f;
one_sse.c4=1.0f;
b=(float)(ldexp(1.0,-24));
one_bit_sse.c1=b;
one_bit_sse.c2=b;
one_bit_sse.c3=b;
one_bit_sse.c4=b;
for (k=0;k<96;k++)
{
next[k]=(k+1)%96;
if ((k%4)==3)
next[k]=(k+5)%96;
}
}
void RandGen::RanLxd::rlxd_init(int level,int seed)
{
int i,k,l;
int ibit,jbit,xbit[31];
int ix,iy;
define_constants();
if (level==1)
rlxd_pr=202;
else if (level==2)
rlxd_pr=397;
else
error(1);
i=seed;
for (k=0;k<31;k++)
{
xbit[k]=i%2;
i/=2;
}
if ((seed<=0)||(i!=0))
error(2);
ibit=0;
jbit=18;
for (i=0;i<4;i++)
{
for (k=0;k<24;k++)
{
ix=0;
for (l=0;l<24;l++)
{
iy=xbit[ibit];
ix=2*ix+iy;
xbit[ibit]=(xbit[ibit]+xbit[jbit])%2;
ibit=(ibit+1)%31;
jbit=(jbit+1)%31;
}
if ((k%4)!=i)
ix=16777215-ix;
rlxd_x.num[4*k+i]=(float)(ldexp((double)(ix),-24));
}
}
carry.c1=0.0f;
carry.c2=0.0f;
carry.c3=0.0f;
carry.c4=0.0f;
ir=0;
jr=7;
is=91;
is_old=0;
prm=rlxd_pr%12;
init=1;
}
void RandGen::RanLxd::ranlxd(double r[],int n)
{
int k;
if (init==0)
rlxd_init(1,1);
for (k=0;k<n;k++)
{
is=next[is];
if (is==is_old)
update();
r[k]=(double)(rlxd_x.num[is+4])+(double)(one_bit_sse.c1*rlxd_x.num[is]);
}
}
int RandGen::RanLxd::rlxd_size(void) const
{
return(RLXG_STATE_SIZE);
}
void RandGen::RanLxd::rlxd_get(int state[]) const
{
int k;
float base;
if (init==0)
error(3);
base=(float)(ldexp(1.0,24));
state[0]=rlxd_size();
for (k=0;k<96;k++)
state[k+1]=(int)(base*rlxd_x.num[k]);
state[97]=(int)(base*carry.c1);
state[98]=(int)(base*carry.c2);
state[99]=(int)(base*carry.c3);
state[100]=(int)(base*carry.c4);
state[101]=rlxd_pr;
state[102]=ir;
state[103]=jr;
state[104]=is;
}
void RandGen::RanLxd::rlxd_reset(const int state[])
{
int k;
define_constants();
if (state[0]!=rlxd_size())
error(5);
for (k=0;k<96;k++)
{
if ((state[k+1]<0)||(state[k+1]>=167777216))
error(5);
rlxd_x.num[k]=(float)(ldexp((double)(state[k+1]),-24));
}
if (((state[97]!=0)&&(state[97]!=1))||
((state[98]!=0)&&(state[98]!=1))||
((state[99]!=0)&&(state[99]!=1))||
((state[100]!=0)&&(state[100]!=1)))
error(5);
carry.c1=(float)(ldexp((double)(state[97]),-24));
carry.c2=(float)(ldexp((double)(state[98]),-24));
carry.c3=(float)(ldexp((double)(state[99]),-24));
carry.c4=(float)(ldexp((double)(state[100]),-24));
rlxd_pr=state[101];
ir=state[102];
jr=state[103];
is=state[104];
is_old=8*ir;
prm=rlxd_pr%12;
init=1;
if (((rlxd_pr!=202)&&(rlxd_pr!=397))||
(ir<0)||(ir>11)||(jr<0)||(jr>11)||(jr!=((ir+7)%12))||
(is<0)||(is>91))
error(5);
}
#else
#define BASE 0x1000000
#define MASK 0xffffff
#define STEP(pi,pj) \
d=(*pj).c1.c1-(*pi).c1.c1-carry.c1; \
(*pi).c2.c1+=(d<0); \
d+=BASE; \
(*pi).c1.c1=d&MASK; \
d=(*pj).c1.c2-(*pi).c1.c2-carry.c2; \
(*pi).c2.c2+=(d<0); \
d+=BASE; \
(*pi).c1.c2=d&MASK; \
d=(*pj).c1.c3-(*pi).c1.c3-carry.c3; \
(*pi).c2.c3+=(d<0); \
d+=BASE; \
(*pi).c1.c3=d&MASK; \
d=(*pj).c1.c4-(*pi).c1.c4-carry.c4; \
(*pi).c2.c4+=(d<0); \
d+=BASE; \
(*pi).c1.c4=d&MASK; \
d=(*pj).c2.c1-(*pi).c2.c1; \
carry.c1=(d<0); \
d+=BASE; \
(*pi).c2.c1=d&MASK; \
d=(*pj).c2.c2-(*pi).c2.c2; \
carry.c2=(d<0); \
d+=BASE; \
(*pi).c2.c2=d&MASK; \
d=(*pj).c2.c3-(*pi).c2.c3; \
carry.c3=(d<0); \
d+=BASE; \
(*pi).c2.c3=d&MASK; \
d=(*pj).c2.c4-(*pi).c2.c4; \
carry.c4=(d<0); \
d+=BASE; \
(*pi).c2.c4=d&MASK
void RandGen::RanLxd::error(int no) const
{
switch(no)
{
case 0:
LATAN_ERROR(System, "Arithmetic on this machine is not suitable for ranlxd");
break;
case 1:
LATAN_ERROR(Range, "Bad choice of luxury level (should be 1 or 2)");
break;
case 2:
LATAN_ERROR(Range, "Bad choice of seed (should be between 1 and 2^31-1)");
break;
case 3:
LATAN_ERROR(Runtime, "Undefined state (ranlxd is not initialized)");
case 4:
LATAN_ERROR(System, "Arithmetic on this machine is not suitable for ranlxd");
break;
case 5:
LATAN_ERROR(Logic, "Unexpected input data");
break;
}
}
void RandGen::RanLxd::update(void)
{
int k,kmax,d;
rlxd_dble_vec_t *pmin,*pmax,*pi,*pj;
kmax=rlxd_pr;
pmin=&rlxd_x.vec[0];
pmax=pmin+12;
pi=&rlxd_x.vec[ir];
pj=&rlxd_x.vec[jr];
for (k=0;k<kmax;k++)
{
STEP(pi,pj);
pi+=1;
pj+=1;
if (pi==pmax)
pi=pmin;
if (pj==pmax)
pj=pmin;
}
ir+=prm;
jr+=prm;
if (ir>=12)
ir-=12;
if (jr>=12)
jr-=12;
is=8*ir;
is_old=is;
}
void RandGen::RanLxd::define_constants(void)
{
int k;
one_bit=ldexp(1.0,-24);
for (k=0;k<96;k++)
{
next[k]=(k+1)%96;
if ((k%4)==3)
next[k]=(k+5)%96;
}
}
void RandGen::RanLxd::rlxd_init(int level,int seed)
{
int i,k,l;
int ibit,jbit,xbit[31];
int ix,iy;
if ((INT_MAX<2147483647)||(FLT_RADIX!=2)||(FLT_MANT_DIG<24)||
(DBL_MANT_DIG<48))
error(0);
define_constants();
if (level==1)
rlxd_pr=202;
else if (level==2)
rlxd_pr=397;
else
error(1);
i=seed;
for (k=0;k<31;k++)
{
xbit[k]=i%2;
i/=2;
}
if ((seed<=0)||(i!=0))
error(2);
ibit=0;
jbit=18;
for (i=0;i<4;i++)
{
for (k=0;k<24;k++)
{
ix=0;
for (l=0;l<24;l++)
{
iy=xbit[ibit];
ix=2*ix+iy;
xbit[ibit]=(xbit[ibit]+xbit[jbit])%2;
ibit=(ibit+1)%31;
jbit=(jbit+1)%31;
}
if ((k%4)!=i)
ix=16777215-ix;
rlxd_x.num[4*k+i]=ix;
}
}
carry.c1=0;
carry.c2=0;
carry.c3=0;
carry.c4=0;
ir=0;
jr=7;
is=91;
is_old=0;
prm=rlxd_pr%12;
init=1;
}
void RandGen::RanLxd::ranlxd(double r[],int n)
{
int k;
if (init==0)
rlxd_init(1,1);
for (k=0;k<n;k++)
{
is=next[is];
if (is==is_old)
update();
r[k]=one_bit*((double)(rlxd_x.num[is+4])+one_bit*(double)(rlxd_x.num[is]));
}
}
int RandGen::RanLxd::rlxd_size(void) const
{
return(RLXG_STATE_SIZE);
}
void RandGen::RanLxd::rlxd_get(int state[]) const
{
int k;
if (init==0)
error(3);
state[0]=rlxd_size();
for (k=0;k<96;k++)
state[k+1]=rlxd_x.num[k];
state[97]=carry.c1;
state[98]=carry.c2;
state[99]=carry.c3;
state[100]=carry.c4;
state[101]=rlxd_pr;
state[102]=ir;
state[103]=jr;
state[104]=is;
}
void RandGen::RanLxd::rlxd_reset(const int state[])
{
int k;
if ((INT_MAX<2147483647)||(FLT_RADIX!=2)||(FLT_MANT_DIG<24)||
(DBL_MANT_DIG<48))
error(4);
define_constants();
if (state[0]!=rlxd_size())
error(5);
for (k=0;k<96;k++)
{
if ((state[k+1]<0)||(state[k+1]>=167777216))
error(5);
rlxd_x.num[k]=state[k+1];
}
if (((state[97]!=0)&&(state[97]!=1))||
((state[98]!=0)&&(state[98]!=1))||
((state[99]!=0)&&(state[99]!=1))||
((state[100]!=0)&&(state[100]!=1)))
error(5);
carry.c1=state[97];
carry.c2=state[98];
carry.c3=state[99];
carry.c4=state[100];
rlxd_pr=state[101];
ir=state[102];
jr=state[103];
is=state[104];
is_old=8*ir;
prm=rlxd_pr%12;
init=1;
if (((rlxd_pr!=202)&&(rlxd_pr!=397))||
(ir<0)||(ir>11)||(jr<0)||(jr>11)||(jr!=((ir+7)%12))||
(is<0)||(is>91))
error(5);
}
#endif
// constructors ////////////////////////////////////////////////////////////////
RandGen::RandGen(void)
{
generator_.rlxd_init(RLXD_LEVEL, (int)time(NULL));
}
RandGen::RandGen(const int seed)
{
generator_.rlxd_init(RLXD_LEVEL, seed);
}
RandGen::RandGen(const RandGenState &state)
{
setState(state);
}
// state management ////////////////////////////////////////////////////////////
RandGenState RandGen::getState(void) const
{
RandGenState state;
generator_.rlxd_get(state.data());
return state;
}
void RandGen::setState(const RandGenState &state)
{
generator_.rlxd_reset(state.data());
}
// generators //////////////////////////////////////////////////////////////////
double RandGen::uniform(const double a, const double b)
{
double rx;
generator_.ranlxd(&rx, 1);
return (b-a)*rx + a;
}
unsigned int RandGen::discreteUniform(const unsigned int n)
{
return ((unsigned int)(uniform()*(double)(n)));
}
double RandGen::gaussian(const double mean, const double sigma)
{
double rx, ry, sqNrm;
do
{
rx = uniform(-1.0, 1.0);
ry = uniform(-1.0, 1.0);
sqNrm = rx*rx + ry*ry;
} while ((sqNrm > 1.0)||(sqNrm == 0.0));
return sigma*rx*sqrt(-2.0*log(sqNrm)/sqNrm) + mean;
}

View File

@ -1,103 +0,0 @@
/*
* RandGen.hpp, part of LatAnalyze 3
*
* Copyright (C) 2013 - 2015 Antonin Portelli
*
* LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LatAnalyze 3 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Latan_RandGen_hpp_
#define Latan_RandGen_hpp_
#include <LatAnalyze/Global.hpp>
#include <LatAnalyze/IoObject.hpp>
#define RLXG_STATE_SIZE 105u
BEGIN_LATAN_NAMESPACE
class RandGenState: public Array<int, RLXG_STATE_SIZE, 1>,
public IoObject
{
private:
typedef Array<int, RLXG_STATE_SIZE, 1> Base;
public:
// destructor
virtual ~RandGenState(void) = default;
// IO type
IoType getType(void) const;
};
/******************************************************************************
* Random generator class *
******************************************************************************/
class RandGen
{
private:
// Martin Luescher's ranlxd generator interface
class RanLxd
{
private:
typedef struct alignas(16)
{
float c1,c2,c3,c4;
} rlxd_vec_t;
typedef struct alignas(16)
{
rlxd_vec_t c1,c2;
} rlxd_dble_vec_t;
public:
RanLxd(void);
~RanLxd(void) = default;
void ranlxd(double r[],int n);
void rlxd_init(int level,int seed);
int rlxd_size(void) const;
void rlxd_get(int state[]) const;
void rlxd_reset(const int state[]);
private:
void error(int no) const;
void update(void);
void define_constants(void);
private:
int init{0}, rlxd_pr, prm, ir, jr, is, is_old, next[96];
rlxd_vec_t one_sse, one_bit_sse, carry;
double one_bit;
union alignas(16)
{
rlxd_dble_vec_t vec[12];
float num[96];
} rlxd_x;
};
public:
// constructors
RandGen(void);
explicit RandGen(const int seed);
explicit RandGen(const RandGenState &state);
// destructor
virtual ~RandGen(void) = default;
// state management
RandGenState getState(void) const;
void setState(const RandGenState &state);
// generators
double uniform(const double a = 0.0, const double b = 1.0);
unsigned int discreteUniform(const unsigned int n);
double gaussian(const double mean = 0.0, const double sigma = 1.0);
private:
RanLxd generator_;
};
END_LATAN_NAMESPACE
#endif // Latan_RandGen_hpp_

View File

@ -1,7 +1,7 @@
/* /*
* RootFinder.cpp, part of LatAnalyze 3 * RootFinder.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
* RootFinder.hpp, part of LatAnalyze 3 * RootFinder.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
* Solver.cpp, part of LatAnalyze 3 * Solver.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
/* /*
* Solver.hpp, part of LatAnalyze 3 * Solver.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -31,7 +31,7 @@ BEGIN_LATAN_NAMESPACE
class Solver class Solver
{ {
public: public:
static const unsigned int defaultMaxIteration = 1000u; static const unsigned int defaultMaxIteration = 10000u;
static constexpr double defaultPrec = 1.0e-7; static constexpr double defaultPrec = 1.0e-7;
public: public:
enum class Verbosity enum class Verbosity

View File

@ -1,7 +1,7 @@
/* /*
* MatSample.cpp, part of LatAnalyze 3 * StatArray.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -17,7 +17,7 @@
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>. * along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <LatAnalyze/MatSample.hpp> #include <LatAnalyze/StatArray.hpp>
#include <LatAnalyze/includes.hpp> #include <LatAnalyze/includes.hpp>
using namespace std; using namespace std;
@ -25,7 +25,7 @@ using namespace std;
namespace Latan namespace Latan
{ {
template <> template <>
IoObject::IoType MatSample<double>::getType(void) const IoObject::IoType StatArray<Mat<double>, -1>::getType(void) const
{ {
return IoType::dMatSample; return IoType::dMatSample;
} }

View File

@ -1,7 +1,7 @@
/* /*
* StatArray.hpp, part of LatAnalyze 3 * StatArray.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -22,7 +22,6 @@
#include <LatAnalyze/Global.hpp> #include <LatAnalyze/Global.hpp>
#include <LatAnalyze/Mat.hpp> #include <LatAnalyze/Mat.hpp>
#include <iostream>
#define FOR_STAT_ARRAY(ar, i) \ #define FOR_STAT_ARRAY(ar, i) \
for (Latan::Index i = -(ar).offset; i < (ar).size(); ++i) for (Latan::Index i = -(ar).offset; i < (ar).size(); ++i)
@ -33,7 +32,7 @@ BEGIN_LATAN_NAMESPACE
* Array class with statistics * * Array class with statistics *
******************************************************************************/ ******************************************************************************/
template <typename T, Index os = 0> template <typename T, Index os = 0>
class StatArray: public Array<T, dynamic, 1> class StatArray: public Array<T, dynamic, 1>, public IoObject
{ {
protected: protected:
typedef Array<T, dynamic, 1> Base; typedef Array<T, dynamic, 1> Base;
@ -60,8 +59,10 @@ public:
T variance(const Index pos = 0, const Index n = -1) const; T variance(const Index pos = 0, const Index n = -1) const;
T varianceMatrix(const Index pos = 0, const Index n = -1) const; T varianceMatrix(const Index pos = 0, const Index n = -1) const;
T correlationMatrix(const Index pos = 0, const Index n = -1) const; T correlationMatrix(const Index pos = 0, const Index n = -1) const;
// IO type
virtual IoType getType(void) const;
public: public:
static const Index offset = os; static constexpr Index offset = os;
}; };
// reduction operations // reduction operations
@ -77,12 +78,10 @@ namespace ReducOp
} }
// Sample types // Sample types
#define SAMPLE_OFFSET 1 const int central = -1;
const int central = -SAMPLE_OFFSET;
template <typename T> template <typename T>
using Sample = StatArray<T, SAMPLE_OFFSET>; using Sample = StatArray<T, 1>;
typedef Sample<double> DSample; typedef Sample<double> DSample;
typedef Sample<std::complex<double>> CSample; typedef Sample<std::complex<double>> CSample;
@ -273,6 +272,13 @@ namespace ReducOp
} }
} }
// IO type /////////////////////////////////////////////////////////////////////
template <typename T, Index os>
IoObject::IoType StatArray<T, os>::getType(void) const
{
return IoType::noType;
}
END_LATAN_NAMESPACE END_LATAN_NAMESPACE
#endif // Latan_StatArray_hpp_ #endif // Latan_StatArray_hpp_

View File

@ -1,7 +1,7 @@
/* /*
* TabFunction.cpp, part of LatAnalyze 3 * TabFunction.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -34,12 +34,12 @@ TabFunction::TabFunction(const DVec &x, const DVec &y,
setData(x, y); setData(x, y);
} }
TabFunction::TabFunction(const XYStatData &data, const Index i, const Index j, //TabFunction::TabFunction(const XYStatData &data, const Index i, const Index j,
const InterpType interpType) // const InterpType interpType)
: interpType_(interpType) //: interpType_(interpType)
{ //{
setData(data, i, j); // setData(data, i, j);
} //}
// access ////////////////////////////////////////////////////////////////////// // access //////////////////////////////////////////////////////////////////////
void TabFunction::setData(const DVec &x, const DVec &y) void TabFunction::setData(const DVec &x, const DVec &y)
@ -54,10 +54,10 @@ void TabFunction::setData(const DVec &x, const DVec &y)
} }
} }
void TabFunction::setData(const XYStatData &data, const Index i, const Index j) //void TabFunction::setData(const XYStatData &data, const Index i, const Index j)
{ //{
setData(data.x(i), data.y(j)); // setData(data.x(i), data.y(j));
} //}
// function call /////////////////////////////////////////////////////////////// // function call ///////////////////////////////////////////////////////////////
double TabFunction::operator()(const double *arg) const double TabFunction::operator()(const double *arg) const
@ -154,11 +154,11 @@ DoubleFunction Latan::interpolate(const DVec &x, const DVec &y,
return TabFunction(x, y, interpType).makeFunction(); return TabFunction(x, y, interpType).makeFunction();
} }
DoubleFunction Latan::interpolate(const XYStatData &data, const Index i, //DoubleFunction Latan::interpolate(const XYStatData &data, const Index i,
const Index j, const InterpType interpType) // const Index j, const InterpType interpType)
{ //{
return TabFunction(data, i, j, interpType).makeFunction(); // return TabFunction(data, i, j, interpType).makeFunction();
} //}
map<double, double>::const_iterator TabFunction::nearest(const double x) const map<double, double>::const_iterator TabFunction::nearest(const double x) const
{ {

View File

@ -1,7 +1,7 @@
/* /*
* TabFunction.hpp, part of LatAnalyze 3 * TabFunction.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -20,8 +20,6 @@
#ifndef Latan_TabFunction_hpp_ #ifndef Latan_TabFunction_hpp_
#define Latan_TabFunction_hpp_ #define Latan_TabFunction_hpp_
#include <algorithm>
#include <map>
#include <LatAnalyze/Global.hpp> #include <LatAnalyze/Global.hpp>
#include <LatAnalyze/Function.hpp> #include <LatAnalyze/Function.hpp>
#include <LatAnalyze/Math.hpp> #include <LatAnalyze/Math.hpp>
@ -47,13 +45,13 @@ public:
TabFunction(void) = default; TabFunction(void) = default;
TabFunction(const DVec &x, const DVec &y, TabFunction(const DVec &x, const DVec &y,
const InterpType interpType = InterpType::LINEAR); const InterpType interpType = InterpType::LINEAR);
TabFunction(const XYStatData &data, const Index i = 0, const Index j = 0, //TabFunction(const XYStatData &data, const Index i = 0, const Index j = 0,
const InterpType interpType = InterpType::LINEAR); // const InterpType interpType = InterpType::LINEAR);
// destructor // destructor
virtual ~TabFunction(void) = default; virtual ~TabFunction(void) = default;
// access // access
void setData(const DVec &x, const DVec &y); void setData(const DVec &x, const DVec &y);
void setData(const XYStatData &data, const Index i = 0, const Index j = 0); // void setData(const XYStatData &data, const Index i = 0, const Index j = 0);
// function call // function call
double operator()(const double *arg) const; double operator()(const double *arg) const;
// factory // factory
@ -67,9 +65,9 @@ private:
DoubleFunction interpolate(const DVec &x, const DVec &y, DoubleFunction interpolate(const DVec &x, const DVec &y,
const InterpType interpType = InterpType::LINEAR); const InterpType interpType = InterpType::LINEAR);
DoubleFunction interpolate(const XYStatData &data, const Index i = 0, //DoubleFunction interpolate(const XYStatData &data, const Index i = 0,
const Index j = 0, // const Index j = 0,
const InterpType interpType = InterpType::LINEAR); // const InterpType interpType = InterpType::LINEAR);
END_LATAN_NAMESPACE END_LATAN_NAMESPACE

View File

@ -1,7 +1,7 @@
/* /*
* XYSampleData.cpp, part of LatAnalyze 3 * XYSampleData.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -18,12 +18,11 @@
*/ */
#include <LatAnalyze/XYSampleData.hpp> #include <LatAnalyze/XYSampleData.hpp>
#include <LatAnalyze/Math.hpp>
#include <LatAnalyze/includes.hpp> #include <LatAnalyze/includes.hpp>
#include <LatAnalyze/Math.hpp>
using namespace std; using namespace std;
using namespace Latan; using namespace Latan;
using namespace Math;
/****************************************************************************** /******************************************************************************
* SampleFitResult implementation * * SampleFitResult implementation *
@ -53,28 +52,33 @@ double SampleFitResult::getNDof(void) const
return static_cast<double>(nDof_); return static_cast<double>(nDof_);
} }
double SampleFitResult::getPValue(const Index s) const Index SampleFitResult::getNPar(void) const
{ {
return chi2PValue(getChi2(s), getNDof()); return nPar_;
} }
const DoubleFunction & SampleFitResult::getModel(const Index s, double SampleFitResult::getPValue(const Index s) const
{
return Math::chi2PValue(getChi2(s), getNDof());
}
const DoubleFunction & SampleFitResult::getModel(const Index s,
const Index j) const const Index j) const
{ {
return model_[static_cast<unsigned int>(j)][s]; return model_[j][s];
} }
const DoubleFunctionSample & SampleFitResult::getModel( const DoubleFunctionSample & SampleFitResult::getModel(
const PlaceHolder ph __dumb, const PlaceHolder ph __dumb,
const Index j) const const Index j) const
{ {
return model_[static_cast<unsigned int>(j)]; return model_[j];
} }
FitResult SampleFitResult::getFitResult(const Index s) const FitResult SampleFitResult::getFitResult(const Index s) const
{ {
FitResult fit; FitResult fit;
fit = (*this)[s]; fit = (*this)[s];
fit.chi2_ = getChi2(); fit.chi2_ = getChi2();
fit.nDof_ = static_cast<Index>(getNDof()); fit.nDof_ = static_cast<Index>(getNDof());
@ -83,292 +87,406 @@ FitResult SampleFitResult::getFitResult(const Index s) const
{ {
fit.model_[k] = model_[k][s]; fit.model_[k] = model_[k][s];
} }
return fit; return fit;
} }
// IO //////////////////////////////////////////////////////////////////////////
void SampleFitResult::print(const bool printXsi, ostream &out) const
{
char buf[256];
Index pMax = printXsi ? size() : nPar_;
DMat err = this->variance().cwiseSqrt();
sprintf(buf, "chi^2/dof= %.1f/%d= %.2f -- p-value= %.2e", getChi2(),
static_cast<int>(getNDof()), getChi2PerDof(), getPValue());
out << buf << endl;
for (Index p = 0; p < pMax; ++p)
{
sprintf(buf, "%8s= % e +/- %e", parName_[p].c_str(),
(*this)[central](p), err(p));
out << buf << endl;
}
}
/****************************************************************************** /******************************************************************************
* XYSampleData implementation * * XYSampleData implementation *
******************************************************************************/ ******************************************************************************/
// constructors //////////////////////////////////////////////////////////////// // constructor /////////////////////////////////////////////////////////////////
XYSampleData::XYSampleData(const Index nData, const Index xDim, XYSampleData::XYSampleData(const Index nSample)
const Index yDim, const Index nSample) : nSample_(nSample)
{}
// data access /////////////////////////////////////////////////////////////////
DSample & XYSampleData::x(const Index r, const Index i)
{ {
resize(nData, xDim, yDim, nSample); checkXIndex(r, i);
scheduleDataInit();
scheduleComputeVarMat();
if (xData_[i][r].size() == 0)
{
xData_[i][r].resize(nSample_);
}
return xData_[i][r];
} }
// access ////////////////////////////////////////////////////////////////////// const DSample & XYSampleData::x(const Index r, const Index i) const
const XYStatData & XYSampleData::getData(const Index s)
{ {
setDataToSample(s); checkXIndex(r, i);
return xData_[i][r];
}
const DMatSample & XYSampleData::x(const Index k)
{
checkDataIndex(k);
updateXMap();
return xMap_.at(k);
}
DSample & XYSampleData::y(const Index k, const Index j)
{
checkYDim(j);
if (!pointExists(k, j))
{
registerDataPoint(k, j);
}
scheduleDataInit();
scheduleComputeVarMat();
if (yData_[j][k].size() == 0)
{
yData_[j][k].resize(nSample_);
}
return yData_[j][k];
}
const DSample & XYSampleData::y(const Index k, const Index j) const
{
checkPoint(k, j);
return yData_[j].at(k);
}
const DMat & XYSampleData::getXXVar(const Index i1, const Index i2)
{
checkXDim(i1);
checkXDim(i2);
computeVarMat();
return data_.getXXVar(i1, i2);
}
const DMat & XYSampleData::getYYVar(const Index j1, const Index j2)
{
checkYDim(j1);
checkYDim(j2);
computeVarMat();
return data_.getYYVar(j1, j2);
}
const DMat & XYSampleData::getXYVar(const Index i, const Index j)
{
checkXDim(i);
checkYDim(j);
computeVarMat();
return data_.getXYVar(i, j);
}
DVec XYSampleData::getXError(const Index i)
{
checkXDim(i);
computeVarMat();
return data_.getXError(i);
}
DVec XYSampleData::getYError(const Index j)
{
checkYDim(j);
computeVarMat();
return data_.getYError(j);
}
// get total fit variance matrix and its pseudo-inverse ////////////////////////
const DMat & XYSampleData::getFitVarMat(void)
{
computeVarMat();
return data_.getFitVarMat();
}
const DMat & XYSampleData::getFitVarMatPInv(void)
{
computeVarMat();
return data_.getFitVarMatPInv();
}
// set data to a particular sample /////////////////////////////////////////////
void XYSampleData::setDataToSample(const Index s)
{
if (initData_ or (s != dataSample_))
{
for (Index i = 0; i < getNXDim(); ++i)
for (Index r = 0; r < getXSize(i); ++r)
{
data_.x(r, i) = xData_[i][r][s];
}
for (Index j = 0; j < getNYDim(); ++j)
for (auto &p: yData_[j])
{
data_.y(p.first, j) = p.second[s];
}
dataSample_ = s;
initData_ = false;
}
}
// get internal XYStatData /////////////////////////////////////////////////////
const XYStatData & XYSampleData::getData(void)
{
setDataToSample(central);
return data_; return data_;
} }
void XYSampleData::resize(const Index nData, const Index xDim,
const Index yDim, const Index nSample)
{
FitInterface::resize(nData, xDim, yDim);
x_.resize(nSample);
x_.resizeMat(nData, xDim);
y_.resize(nSample);
y_.resizeMat(nData, yDim);
data_.resize(nData, xDim, yDim);
isCovarianceInit_ = false;
}
XYSampleData::SampleBlock XYSampleData::x(const PlaceHolder ph1 __dumb,
const PlaceHolder ph2 __dumb)
{
isCovarianceInit_ = false;
return x_.block(0, 0, getNData(), getXDim());
}
XYSampleData::ConstSampleBlock XYSampleData::x(const PlaceHolder ph1 __dumb,
const PlaceHolder ph2 __dumb)
const
{
return x_.block(0, 0, getNData(), getXDim());
}
XYSampleData::SampleBlock XYSampleData::x(const Index i,
const PlaceHolder ph2 __dumb)
{
isCovarianceInit_ = false;
return x_.block(0, i, getNData(), 1);
}
XYSampleData::ConstSampleBlock XYSampleData::x(const Index i,
const PlaceHolder ph2 __dumb)
const
{
return x_.block(0, i, getNData(), 1);
}
XYSampleData::SampleBlock XYSampleData::x(const PlaceHolder ph1 __dumb,
const Index k)
{
isCovarianceInit_ = false;
return x_.block(k, 0, 1, getXDim());
}
XYSampleData::ConstSampleBlock XYSampleData::x(const PlaceHolder ph1 __dumb,
const Index k) const
{
return x_.block(k, 0, 1, getXDim());
}
XYSampleData::SampleBlock XYSampleData::x(const Index i, const Index k)
{
isCovarianceInit_ = false;
return x_.block(k, i, 1, 1);
}
XYSampleData::ConstSampleBlock XYSampleData::x(const Index i, const Index k)
const
{
return x_.block(k, i, 1, 1);
}
XYSampleData::SampleBlock XYSampleData::y(const PlaceHolder ph1 __dumb,
const PlaceHolder ph2 __dumb)
{
isCovarianceInit_ = false;
return y_.block(0, 0, getNData(), getYDim());
}
XYSampleData::ConstSampleBlock XYSampleData::y(const PlaceHolder ph1 __dumb,
const PlaceHolder ph2 __dumb)
const
{
return y_.block(0, 0, getNData(), getYDim());
}
XYSampleData::SampleBlock XYSampleData::y(const Index j,
const PlaceHolder ph2 __dumb)
{
isCovarianceInit_ = false;
return y_.block(0, j, getNData(), 1);
}
XYSampleData::ConstSampleBlock XYSampleData::y(const Index j,
const PlaceHolder ph2 __dumb)
const
{
return y_.block(0, j, getNData(), 1);
}
XYSampleData::SampleBlock XYSampleData::y(const PlaceHolder ph1 __dumb,
const Index k)
{
isCovarianceInit_ = false;
return y_.block(k, 0, 1, getYDim());
}
XYSampleData::ConstSampleBlock XYSampleData::y(const PlaceHolder ph1 __dumb,
const Index k) const
{
return y_.block(k, 0, 1, getYDim());
}
XYSampleData::SampleBlock XYSampleData::y(const Index j, const Index k)
{
isCovarianceInit_ = false;
return y_.block(k, j, 1, 1);
}
XYSampleData::ConstSampleBlock XYSampleData::y(const Index j, const Index k)
const
{
return y_.block(k, j, 1, 1);
}
// fit ///////////////////////////////////////////////////////////////////////// // fit /////////////////////////////////////////////////////////////////////////
SampleFitResult XYSampleData::fit(Minimizer &minimizer, const DVec &init, SampleFitResult XYSampleData::fit(std::vector<Minimizer *> &minimizer,
const std::vector<const DoubleModel *> &modelVector) const DVec &init,
const std::vector<const DoubleModel *> &v)
{ {
const Index nSample = x_.size(); computeVarMat();
FitResult sampleResult;
SampleFitResult result;
DVec initBuf = init;
result.resize(nSample); SampleFitResult result;
result.chi2_.resize(nSample); FitResult sampleResult;
FOR_STAT_ARRAY(x_, s) DVec initCopy = init;
result.resize(nSample_);
result.chi2_.resize(nSample_);
result.model_.resize(v.size());
FOR_STAT_ARRAY(result, s)
{ {
// reinit chi^2 for central value only setDataToSample(s);
if (s == central) if (s == central)
{ {
data_.reinitChi2(true); sampleResult = data_.fit(minimizer, initCopy, v);
} }
else else
{ {
data_.reinitChi2(false); sampleResult = data_.fit(*(minimizer.back()), initCopy, v);
} }
initCopy = sampleResult.segment(0, initCopy.size());
// set data
setDataToSample(s);
// fit
sampleResult = data_.fit(minimizer, initBuf, modelVector);
if (s == central)
{
initBuf = sampleResult;
}
// store result
result[s] = sampleResult; result[s] = sampleResult;
result.chi2_[s] = sampleResult.getChi2(); result.chi2_[s] = sampleResult.getChi2();
result.nDof_ = sampleResult.getNDof(); for (unsigned int j = 0; j < v.size(); ++j)
result.model_.resize(modelVector.size());
for (unsigned int j = 0; j < modelVector.size(); ++j)
{ {
result.model_[j].resize(nSample); result.model_[j].resize(nSample_);
result.model_[j][s] = sampleResult.getModel(j); result.model_[j][s] = sampleResult.getModel(j);
} }
} }
result.nPar_ = sampleResult.getNPar();
result.nDof_ = sampleResult.nDof_;
result.parName_ = sampleResult.parName_;
return result; return result;
} }
void XYSampleData::setDataToSample(const Index s) SampleFitResult XYSampleData::fit(Minimizer &minimizer,
const DVec &init,
const std::vector<const DoubleModel *> &v)
{ {
// compute covariance matrices if necessary vector<Minimizer *> mv{&minimizer};
if (!isCovarianceInit_)
{
DMatSample buf1, buf2;
for (Index i2 = 0; i2 < getXDim(); ++i2)
for (Index i1 = 0; i1 < getXDim(); ++i1)
{
buf1 = x(i1);
buf2 = x(i2);
data_.xxVar(i1, i2) = buf1.covarianceMatrix(buf2);
}
for (Index j2 = 0; j2 < getYDim(); ++j2)
for (Index j1 = 0; j1 < getYDim(); ++j1)
{
buf1 = y(j1);
buf2 = y(j2);
data_.yyVar(j1, j2) = buf1.covarianceMatrix(buf2);
}
for (Index i = 0; i < getXDim(); ++i)
for (Index j = 0; j < getYDim(); ++j)
{
buf1 = y(j);
buf2 = x(i);
data_.yxVar(j, i) = buf1.covarianceMatrix(buf2);
}
isCovarianceInit_ = true;
}
// copy interface to sample data return fit(mv, init, v);
data_.setFitInterface(*this);
// set data
data_.x() = x_[s];
data_.y() = y_[s];
} }
// residuals /////////////////////////////////////////////////////////////////// // residuals ///////////////////////////////////////////////////////////////////
XYSampleData XYSampleData::getResiduals(const SampleFitResult &fit) const XYSampleData XYSampleData::getResiduals(const SampleFitResult &fit)
{ {
const Index nSample = x_.size();
XYSampleData res(*this); XYSampleData res(*this);
DMatSample xBuf(nSample, getXDim(), 1), tmp(nSample, 1, 1);
for (Index j = 0; j < getNYDim(); ++j)
for (Index j = 0; j < res.getYDim(); ++j)
{ {
const DoubleFunctionSample &f = fit.getModel(_, j); const DoubleFunctionSample &f = fit.getModel(_, j);
for (Index k = 0; k < res.getNData(); ++k) for (auto &p: yData_[j])
{ {
xBuf = this->x(_, k); res.y(p.first, j) -= f(x(p.first));
tmp = this->y(j, k);
FOR_STAT_ARRAY(xBuf, s)
{
tmp[s](0) -= f[s](xBuf[s].transpose());
}
res.y(j, k) = tmp;
} }
} }
return res; return res;
} }
XYSampleData XYSampleData::getPartialResiduals(const SampleFitResult &fit, XYSampleData XYSampleData::getPartialResiduals(const SampleFitResult &fit,
const DVec &x, const DVec &ref, const Index i)
const Index i) const
{ {
const Index nSample = x_.size();
XYSampleData res(*this); XYSampleData res(*this);
DMatSample xBuf(nSample, getXDim(), 1), tmp(nSample, 1, 1); DMatSample buf(nSample_);
DVec buf(x);
buf.fill(ref);
for (Index j = 0; j < res.getYDim(); ++j) for (Index j = 0; j < getNYDim(); ++j)
{ {
const DoubleFunctionSample &f = fit.getModel(_, j); const DoubleFunctionSample &f = fit.getModel(_, j);
for (Index k = 0; k < res.getNData(); ++k) for (auto &p: yData_[j])
{ {
xBuf = this->x(_, k); FOR_STAT_ARRAY(buf, s)
tmp = this->y(j, k);
FOR_STAT_ARRAY(xBuf, s)
{ {
buf(i) = xBuf[s](i); buf[s](i) = x(p.first)[s](i);
tmp[s](0) -= f[s](xBuf[s].transpose()) - f[s](buf);
} }
res.y(j, k) = tmp; res.y(p.first, j) -= f(x(p.first)) - f(buf);
} }
} }
return res; return res;
} }
// buffer list of x vectors ////////////////////////////////////////////////////
void XYSampleData::scheduleXMapInit(void)
{
initXMap_ = true;
}
void XYSampleData::updateXMap(void)
{
if (initXMap_)
{
for (Index s = central; s < nSample_; ++s)
{
setDataToSample(s);
for (auto k: getDataIndexSet())
{
if (s == central)
{
xMap_[k].resize(nSample_);
}
xMap_[k][s] = data_.x(k);
}
}
initXMap_ = false;
}
}
// schedule data initilization from samples ////////////////////////////////////
void XYSampleData::scheduleDataInit(void)
{
initData_ = true;
}
// variance matrix computation /////////////////////////////////////////////////
void XYSampleData::scheduleComputeVarMat(void)
{
computeVarMat_ = true;
}
void XYSampleData::computeVarMat(void)
{
if (computeVarMat_)
{
// initialize data if necessary
setDataToSample(central);
// compute relevant sizes
Index size = 0, ySize = 0;
for (Index j = 0; j < getNYDim(); ++j)
{
size += getYSize(j);
}
ySize = size;
for (Index i = 0; i < getNXDim(); ++i)
{
size += getXSize(i);
}
// compute total matrix
DMatSample z(nSample_, size, 1);
DMat var;
Index a;
FOR_STAT_ARRAY(z, s)
{
a = 0;
for (Index j = 0; j < getNYDim(); ++j)
for (auto &p: yData_[j])
{
z[s](a, 0) = p.second[s];
a++;
}
for (Index i = 0; i < getNXDim(); ++i)
for (Index r = 0; r < getXSize(i); ++r)
{
z[s](a, 0) = xData_[i][r][s];
a++;
}
}
var = z.varianceMatrix();
// assign blocks to data
Index a1, a2;
a1 = ySize;
for (Index i1 = 0; i1 < getNXDim(); ++i1)
{
a2 = ySize;
for (Index i2 = 0; i2 < getNXDim(); ++i2)
{
data_.setXXVar(i1, i2,
var.block(a1, a2, getXSize(i1), getXSize(i2)));
a2 += getXSize(i2);
}
a1 += getXSize(i1);
}
a1 = 0;
for (Index j1 = 0; j1 < getNYDim(); ++j1)
{
a2 = 0;
for (Index j2 = 0; j2 < getNYDim(); ++j2)
{
data_.setYYVar(j1, j2,
var.block(a1, a2, getYSize(j1), getYSize(j2)));
a2 += getYSize(j2);
}
a1 += getYSize(j1);
}
a1 = ySize;
for (Index i = 0; i < getNXDim(); ++i)
{
a2 = 0;
for (Index j = 0; j < getNYDim(); ++j)
{
data_.setXYVar(i, j,
var.block(a1, a2, getXSize(i), getYSize(j)));
a2 += getYSize(j);
}
a1 += getXSize(i);
}
computeVarMat_ = false;
}
if (initVarMat())
{
data_.copyInterface(*this);
scheduleFitVarMatInit(false);
}
}
// create data /////////////////////////////////////////////////////////////////
void XYSampleData::createXData(const string name, const Index nData)
{
data_.addXDim(nData, name);
xData_.push_back(vector<DSample>(nData));
}
void XYSampleData::createYData(const string name)
{
data_.addYDim(name);
yData_.push_back(map<Index, DSample>());
}

View File

@ -1,7 +1,7 @@
/* /*
* XYSampleData.hpp, part of LatAnalyze 3 * XYSampleData.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -22,9 +22,9 @@
#include <LatAnalyze/Global.hpp> #include <LatAnalyze/Global.hpp>
#include <LatAnalyze/FitInterface.hpp> #include <LatAnalyze/FitInterface.hpp>
#include <LatAnalyze/Function.hpp>
#include <LatAnalyze/MatSample.hpp>
#include <LatAnalyze/Minimizer.hpp> #include <LatAnalyze/Minimizer.hpp>
#include <LatAnalyze/MatSample.hpp>
#include <LatAnalyze/Model.hpp>
#include <LatAnalyze/XYStatData.hpp> #include <LatAnalyze/XYStatData.hpp>
BEGIN_LATAN_NAMESPACE BEGIN_LATAN_NAMESPACE
@ -47,90 +47,138 @@ public:
double getChi2PerDof(const Index s = central) const; double getChi2PerDof(const Index s = central) const;
DSample getChi2PerDof(const PlaceHolder ph) const; DSample getChi2PerDof(const PlaceHolder ph) const;
double getNDof(void) const; double getNDof(void) const;
Index getNPar(void) const;
double getPValue(const Index s = central) const; double getPValue(const Index s = central) const;
const DoubleFunction & getModel(const Index s = central, const DoubleFunction & getModel(const Index s = central,
const Index j = 0) const; const Index j = 0) const;
const DoubleFunctionSample & getModel(const PlaceHolder ph, const DoubleFunctionSample & getModel(const PlaceHolder ph,
const Index j = 0) const; const Index j = 0) const;
FitResult getFitResult(const Index s = central) const; FitResult getFitResult(const Index s = central) const;
// IO
void print(const bool printXsi = false,
std::ostream &out = std::cout) const;
private: private:
DSample chi2_; DSample chi2_;
double nDof_{0.}; Index nDof_{0}, nPar_{0};
std::vector<DoubleFunctionSample> model_; std::vector<DoubleFunctionSample> model_;
std::vector<std::string> parName_;
}; };
/****************************************************************************** /******************************************************************************
* XYSampleData * * XYSampleData *
****************************************************************************** ******************************************************************************/
* index convention: i: X, j: Y, k: data
*/
class XYSampleData: public FitInterface class XYSampleData: public FitInterface
{ {
public: public:
typedef DMatSample::Block SampleBlock; // constructor
typedef DMatSample::ConstBlock ConstSampleBlock; explicit XYSampleData(const Index nSample);
public:
// constructors
XYSampleData(void) = default;
XYSampleData(const Index nData, const Index xDim, const Index yDim,
const Index nSample);
// destructor // destructor
virtual ~XYSampleData(void) = default; virtual ~XYSampleData(void) = default;
// access // data access
const XYStatData & getData(const Index s = central); DSample & x(const Index r, const Index i);
void resize(const Index nData, const Index xDim, const DSample & x(const Index r, const Index i) const;
const Index yDim, const Index nSample); const DMatSample & x(const Index k);
SampleBlock x(const PlaceHolder ph1 = _, const PlaceHolder ph2 = _); DSample & y(const Index k, const Index j);
ConstSampleBlock x(const PlaceHolder ph1 = _, const DSample & y(const Index k, const Index j) const;
const PlaceHolder ph2 = _) const; template <typename... Ts>
SampleBlock x(const Index i, const PlaceHolder ph2 = _); void setUnidimData(const DMatSample &xData,
ConstSampleBlock x(const Index i, const PlaceHolder ph2 = _) const; const Ts & ...yDatas);
SampleBlock x(const PlaceHolder ph1, const Index k); const DMat & getXXVar(const Index i1, const Index i2);
ConstSampleBlock x(const PlaceHolder ph1, const Index k) const; const DMat & getYYVar(const Index j1, const Index j2);
SampleBlock x(const Index i, const Index k); const DMat & getXYVar(const Index i, const Index j);
ConstSampleBlock x(const Index i, const Index k) const; DVec getXError(const Index i);
SampleBlock y(const PlaceHolder ph1 = _, const PlaceHolder ph2 = _); DVec getYError(const Index j);
ConstSampleBlock y(const PlaceHolder ph1 = _, // get total fit variance matrix and its pseudo-inverse
const PlaceHolder ph2 = _) const; const DMat & getFitVarMat(void);
SampleBlock y(const Index j, const PlaceHolder ph2 = _); const DMat & getFitVarMatPInv(void);
ConstSampleBlock y(const Index j, const PlaceHolder ph2 = _) const; // set data to a particular sample
SampleBlock y(const PlaceHolder ph1, const Index k);
ConstSampleBlock y(const PlaceHolder ph1, const Index k) const;
SampleBlock y(const Index j, const Index k);
ConstSampleBlock y(const Index j, const Index k) const;
// fit
SampleFitResult fit(Minimizer &minimizer, const DVec &init,
const std::vector<const DoubleModel *> &modelVector);
template <typename... Mods>
SampleFitResult fit(Minimizer &minimizer, const DVec &init,
const DoubleModel &model, const Mods... models);
// residuals
XYSampleData getResiduals(const SampleFitResult &fit) const;
XYSampleData getPartialResiduals(const SampleFitResult &fit, const DVec &x,
const Index j) const;
private:
void setDataToSample(const Index s); void setDataToSample(const Index s);
// get internal XYStatData
const XYStatData & getData(void);
// fit
SampleFitResult fit(std::vector<Minimizer *> &minimizer, const DVec &init,
const std::vector<const DoubleModel *> &v);
SampleFitResult fit(Minimizer &minimizer, const DVec &init,
const std::vector<const DoubleModel *> &v);
template <typename... Ts>
SampleFitResult fit(std::vector<Minimizer *> &minimizer, const DVec &init,
const DoubleModel &model, const Ts... models);
template <typename... Ts>
SampleFitResult fit(Minimizer &minimizer, const DVec &init,
const DoubleModel &model, const Ts... models);
// residuals
XYSampleData getResiduals(const SampleFitResult &fit);
XYSampleData getPartialResiduals(const SampleFitResult &fit, const DVec &x,
const Index i);
private: private:
bool isCovarianceInit_; // buffer list of x vectors
DMatSample x_, y_; void scheduleXMapInit(void);
XYStatData data_; void updateXMap(void);
// schedule data initilization from samples
void scheduleDataInit(void);
// variance matrix computation
void scheduleComputeVarMat(void);
void computeVarMat(void);
// create data
virtual void createXData(const std::string name, const Index nData);
virtual void createYData(const std::string name);
private:
std::vector<std::map<Index, DSample>> yData_;
std::vector<std::vector<DSample>> xData_;
std::map<Index, DMatSample> xMap_;
XYStatData data_;
Index nSample_, dataSample_{central};
bool initData_{true}, computeVarMat_{true};
bool initXMap_{true};
}; };
/****************************************************************************** /******************************************************************************
* XYSampleData template implementation * * XYSampleData template implementation *
******************************************************************************/ ******************************************************************************/
template <typename... Ts> template <typename... Ts>
SampleFitResult XYSampleData::fit(Minimizer &minimizer, const DVec &init, void XYSampleData::setUnidimData(const DMatSample &xData, const Ts & ...yDatas)
{
static_assert(static_or<std::is_assignable<DMatSample, Ts>::value...>::value,
"y data arguments are not compatible with DMatSample");
std::vector<const DMatSample *> yData{&yDatas...};
FOR_STAT_ARRAY(xData, s)
FOR_VEC(xData[central], r)
{
x(r, 0)[s] = xData[s](r);
for (unsigned int j = 0; j < yData.size(); ++j)
{
y(r, j)[s] = (*(yData[j]))[s](r);
}
}
}
template <typename... Ts>
SampleFitResult XYSampleData::fit(std::vector<Minimizer *> &minimizer,
const DVec &init,
const DoubleModel &model, const Ts... models) const DoubleModel &model, const Ts... models)
{ {
static_assert(static_or<std::is_assignable<DoubleModel &, Ts>::value...>::value, static_assert(static_or<std::is_assignable<DoubleModel &, Ts>::value...>::value,
"model arguments are not compatible with DoubleModel &"); "model arguments are not compatible with DoubleModel");
std::vector<const DoubleModel *> modelVector{&model, &models...}; std::vector<const DoubleModel *> modelVector{&model, &models...};
return fit(minimizer, init, modelVector); return fit(minimizer, init, modelVector);
} }
template <typename... Ts>
SampleFitResult XYSampleData::fit(Minimizer &minimizer, const DVec &init,
const DoubleModel &model, const Ts... models)
{
static_assert(static_or<std::is_assignable<DoubleModel &, Ts>::value...>::value,
"model arguments are not compatible with DoubleModel");
std::vector<Minimizer *> mv{&minimizer};
return fit(mv, init, model, models...);
}
END_LATAN_NAMESPACE END_LATAN_NAMESPACE
#endif // Latan_XYSampleData_hpp_ #endif // Latan_XYSampleData_hpp_

View File

@ -1,7 +1,7 @@
/* /*
* XYStatData.cpp, part of LatAnalyze 3 * XYStatData.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -23,7 +23,8 @@
using namespace std; using namespace std;
using namespace Latan; using namespace Latan;
using namespace Math;
static constexpr double maxXsiDev = 10.;
/****************************************************************************** /******************************************************************************
* FitResult implementation * * FitResult implementation *
@ -44,272 +45,566 @@ double FitResult::getNDof(void) const
return static_cast<double>(nDof_); return static_cast<double>(nDof_);
} }
Index FitResult::getNPar(void) const
{
return nPar_;
}
double FitResult::getPValue(void) const double FitResult::getPValue(void) const
{ {
return chi2PValue(getChi2(), getNDof());; return Math::chi2PValue(getChi2(), getNDof());;
} }
const DoubleFunction & FitResult::getModel(const Index j) const const DoubleFunction & FitResult::getModel(const Index j) const
{ {
return model_[static_cast<unsigned int>(j)]; return model_[j];
}
// IO //////////////////////////////////////////////////////////////////////////
void FitResult::print(const bool printXsi, ostream &out) const
{
char buf[256];
Index pMax = printXsi ? size() : nPar_;
sprintf(buf, "chi^2/dof= %.1f/%d= %.2f -- p-value= %.2e", getChi2(),
static_cast<int>(getNDof()), getChi2PerDof(), getPValue());
out << buf << endl;
for (Index p = 0; p < pMax; ++p)
{
sprintf(buf, "%8s= %e", parName_[p].c_str(), (*this)(p));
out << buf << endl;
}
} }
/****************************************************************************** /******************************************************************************
* XYStatData implementation * * XYStatData implementation *
******************************************************************************/ ******************************************************************************/
// constructor ///////////////////////////////////////////////////////////////// // data access /////////////////////////////////////////////////////////////////
XYStatData::XYStatData(void) double & XYStatData::x(const Index r, const Index i)
: chi2_(*this)
{}
XYStatData::XYStatData(const Index nData, const Index xDim, const Index yDim)
: XYStatData()
{ {
resize(nData, xDim, yDim); checkXIndex(r, i);
scheduleXMapInit();
scheduleChi2DataVecInit();
return xData_[i](r);
} }
// access ////////////////////////////////////////////////////////////////////// const double & XYStatData::x(const Index r, const Index i) const
void XYStatData::resize(const Index nData, const Index xDim, const Index yDim)
{ {
FitInterface::resize(nData, xDim, yDim); checkXIndex(r, i);
x_.resize(nData, xDim);
y_.resize(nData, yDim); return xData_[i](r);
var_[xx].resize(xDim, xDim); }
var_[yy].resize(yDim, yDim);
var_[yx].resize(yDim, xDim); const DVec & XYStatData::x(const Index k) const
FOR_MAT(var_[xx], i1, i2) {
checkDataIndex(k);
updateXMap();
return xMap_.at(k);
}
double & XYStatData::y(const Index k, const Index j)
{
checkYDim(j);
if (!pointExists(k, j))
{ {
var_[xx](i1, i2).resize(nData, nData); registerDataPoint(k, j);
resizeVarMat();
} }
FOR_MAT(var_[yy], j1, j2) scheduleXMapInit();
scheduleChi2DataVecInit();
return yData_[j][k];
}
const double & XYStatData::y(const Index k, const Index j) const
{
checkPoint(k, j);
return yData_[j].at(k);
}
void XYStatData::setXXVar(const Index i1, const Index i2, const DMat &m)
{
checkXDim(i1);
checkXDim(i2);
checkVarMat(m, xxVar_(i1, i2));
xxVar_(i1, i2) = m;
if (i1 != i2)
{ {
var_[yy](j1, j2).resize(nData, nData); xxVar_(i2, i1) = m.transpose();
} }
FOR_MAT(var_[yx], j, i) scheduleFitVarMatInit();
}
void XYStatData::setYYVar(const Index j1, const Index j2, const DMat &m)
{
checkYDim(j1);
checkYDim(j2);
checkVarMat(m, yyVar_(j1, j2));
yyVar_(j1, j2) = m;
if (j1 != j2)
{ {
var_[yx](j, i).resize(nData, nData); yyVar_(j2, j1) = m.transpose();
} }
scheduleFitVarMatInit();
} }
void XYStatData::reinitChi2(const bool doReinit) void XYStatData::setXYVar(const Index i, const Index j, const DMat &m)
{ {
reinitChi2_ = doReinit; checkXDim(i);
checkYDim(j);
checkVarMat(m, xyVar_(i, j));
xyVar_(i, j) = m;
scheduleFitVarMatInit();
} }
Block<MatBase<double>> XYStatData::x(const PlaceHolder ph1 __dumb, void XYStatData::setXError(const Index i, const DVec &err)
const PlaceHolder ph2 __dumb)
{ {
return x_.block(0, 0, getNData(), getXDim()); checkXDim(i);
checkErrVec(err, xxVar_(i, i));
xxVar_(i, i).diagonal() = err.cwiseProduct(err);
scheduleFitVarMatInit();
} }
ConstBlock<MatBase<double>> XYStatData::x(const PlaceHolder ph1 __dumb, void XYStatData::setYError(const Index j, const DVec &err)
const PlaceHolder ph2 __dumb)
const
{ {
return x_.block(0, 0, getNData(), getXDim()); checkXDim(j);
checkErrVec(err, yyVar_(j, j));
yyVar_(j, j).diagonal() = err.cwiseProduct(err);
scheduleFitVarMatInit();
} }
Block<MatBase<double>> XYStatData::x(const Index i, const DMat & XYStatData::getXXVar(const Index i1, const Index i2) const
const PlaceHolder ph2 __dumb)
{ {
return x_.block(0, i, getNData(), 1); checkXDim(i1);
checkXDim(i2);
return xxVar_(i1, i2);
} }
ConstBlock<MatBase<double>> XYStatData::x(const Index i, const DMat & XYStatData::getYYVar(const Index j1, const Index j2) const
const PlaceHolder ph2 __dumb)
const
{ {
return x_.block(0, i, getNData(), 1); checkYDim(j1);
checkYDim(j2);
return yyVar_(j1, j2);
} }
Block<MatBase<double>> XYStatData::x(const PlaceHolder ph1 __dumb, const DMat & XYStatData::getXYVar(const Index i, const Index j) const
const Index k)
{ {
return x_.block(k, 0, 1, getXDim()); checkXDim(i);
checkYDim(j);
return xyVar_(i, j);
} }
ConstBlock<MatBase<double>> XYStatData::x(const PlaceHolder ph1 __dumb, DVec XYStatData::getXError(const Index i) const
const Index k) const
{ {
return x_.block(k, 0, 1, getXDim()); checkXDim(i);
return xxVar_(i, i).diagonal().cwiseSqrt();
} }
double & XYStatData::x(const Index i, const Index k) DVec XYStatData::getYError(const Index j) const
{ {
return x_(k, i); checkXDim(j);
return yyVar_(j, j).diagonal().cwiseSqrt();
} }
const double & XYStatData::x(const Index i, const Index k) const DMat XYStatData::getTable(const Index i, const Index j) const
{ {
return x_(k, i); checkXDim(i);
checkYDim(j);
DMat table(getYSize(j), 4);
Index row = 0;
for (auto &p: yData_[j])
{
Index k = p.first;
Index r = dataCoord(k)[i];
table(row, 0) = x(k)(i);
table(row, 2) = p.second;
table(row, 1) = xxVar_(i, i).diagonal().cwiseSqrt()(r);
table(row, 3) = yyVar_(j, j).diagonal().cwiseSqrt()(row);
row++;
}
return table;
} }
Block<MatBase<double>> XYStatData::y(const PlaceHolder ph1 __dumb, // get total fit variance matrix ///////////////////////////////////////////////
const PlaceHolder ph2 __dumb) const DMat & XYStatData::getFitVarMat(void)
{ {
return y_.block(0, 0, getNData(), getYDim()); updateFitVarMat();
return fitVar_;
} }
ConstBlock<MatBase<double>> XYStatData::y(const PlaceHolder ph1 __dumb, const DMat & XYStatData::getFitVarMatPInv(void)
const PlaceHolder ph2 __dumb)
const
{ {
return y_.block(0, 0, getNData(), getYDim()); updateFitVarMat();
}
return fitVarInv_;
Block<MatBase<double>> XYStatData::y(const Index j,
const PlaceHolder ph2 __dumb)
{
return y_.block(0, j, getNData(), 1);
}
ConstBlock<MatBase<double>> XYStatData::y(const Index j,
const PlaceHolder ph2 __dumb)
const
{
return y_.block(0, j, getNData(), 1);
}
Block<MatBase<double>> XYStatData::y(const PlaceHolder ph1 __dumb, const Index k)
{
return y_.block(k, 0, 1, getYDim());
}
ConstBlock<MatBase<double>> XYStatData::y(const PlaceHolder ph1 __dumb,
const Index k) const
{
return y_.block(k, 0, 1, getYDim());
}
double & XYStatData::y(const Index j, const Index k)
{
return y_(k, j);
}
const double & XYStatData::y(const Index j, const Index k) const
{
return y_(k, j);
}
#define FULL_BLOCK(m) (m).block(0, 0, (m).rows(), (m).cols())
Block<MatBase<double>> XYStatData::xxVar(const Index i1, const Index i2)
{
return FULL_BLOCK(var_[xx](i1, i2));
}
ConstBlock<MatBase<double>> XYStatData::xxVar(const Index i1,
const Index i2) const
{
return FULL_BLOCK(var_[xx](i1, i2));
}
Block<MatBase<double>> XYStatData::yyVar(const Index j1, const Index j2)
{
return FULL_BLOCK(var_[yy](j1, j2));
}
ConstBlock<MatBase<double>> XYStatData::yyVar(const Index j1,
const Index j2) const
{
return FULL_BLOCK(var_[yy](j1, j2));
}
Block<MatBase<double>> XYStatData::yxVar(const Index j, const Index i)
{
return FULL_BLOCK(var_[yx](j, i));
}
ConstBlock<MatBase<double>> XYStatData::yxVar(const Index j,
const Index i) const
{
return FULL_BLOCK(var_[yx](j, i));
} }
// fit ///////////////////////////////////////////////////////////////////////// // fit /////////////////////////////////////////////////////////////////////////
FitResult XYStatData::fit(Minimizer &minimizer, const DVec &init, FitResult XYStatData::fit(vector<Minimizer *> &minimizer, const DVec &init,
const vector<const DoubleModel *> &modelVector) const vector<const DoubleModel *> &v)
{ {
// initialization // check model consistency
chi2_.setModel(modelVector); checkModelVec(v);
if (reinitChi2_)
// buffering
updateLayout();
updateFitVarMat();
updateChi2DataVec();
// get number of parameters
Index nPar = v[0]->getNPar();
Index nXDim = getNXDim();
Index totalNPar = nPar + layout.totalXSize;
// chi^2 functions
auto corrChi2Func = [this, nPar, nXDim, totalNPar, &v](const double *x)->double
{ {
chi2_.requestInit(); ConstMap<DVec> p(x, totalNPar);
updateChi2ModVec(p, v, nPar, nXDim);
chi2Vec_ = (chi2ModVec_ - chi2DataVec_);
return chi2Vec_.dot(fitVarInv_*chi2Vec_);
};
DoubleFunction corrChi2(corrChi2Func, totalNPar);
auto uncorrChi2Func = [this, nPar, nXDim, totalNPar, &v](const double *x)->double
{
ConstMap<DVec> p(x, totalNPar);
updateChi2ModVec(p, v, nPar, nXDim);
chi2Vec_ = (chi2ModVec_ - chi2DataVec_);
return chi2Vec_.dot(chi2Vec_.cwiseQuotient(fitVar_.diagonal()));
};
DoubleFunction uncorrChi2(uncorrChi2Func, totalNPar);
DoubleFunction &chi2 = hasCorrelations() ? corrChi2 : uncorrChi2;
for (Index p = 0; p < nPar; ++p)
{
chi2.varName().setName(p, v[0]->parName().getName(p));
} }
// initial parameters for (Index p = 0; p < totalNPar - nPar; ++p)
const Index nPoint = getNFitPoint();
DVec fullInit = init;
Index is = 0, kf = 0;
fullInit.conservativeResize(chi2_.getNArg());
for (Index i = 0; i < getXDim(); ++i)
{ {
if (!isXExact(i)) chi2.varName().setName(p + nPar, "xsi_" + strFrom(p));
}
// minimization
FitResult result;
DVec totalInit(totalNPar);
//// set total init vector
totalInit.segment(0, nPar) = init;
totalInit.segment(nPar, layout.totalXSize) =
chi2DataVec_.segment(layout.totalYSize, layout.totalXSize);
for (auto &m: minimizer)
{
m->setInit(totalInit);
if (m->supportLimits())
{ {
kf = 0; //// do not allow more than maxXsiDev std. deviations on the x-axis
for (Index k = 0; k < getNData(); ++k) for (Index p = nPar; p < totalNPar; ++p)
{ {
if (isFitPoint(k)) double err;
{
fullInit(chi2_.getNPar() + nPoint*is + kf) = x(i, k); err = sqrt(fitVar_.diagonal()(layout.totalYSize + p - nPar));
kf++; m->useLowLimit(p);
} m->useHighLimit(p);
m->setLowLimit(p, totalInit(p) - maxXsiDev*err);
m->setHighLimit(p, totalInit(p) + maxXsiDev*err);
} }
is++;
} }
//// minimize and store results
result = (*m)(chi2);
totalInit = result;
} }
minimizer.setInit(fullInit); result.chi2_ = chi2(result);
result.nPar_ = nPar;
// fit result.nDof_ = layout.totalYSize - nPar;
DoubleFunction chi2 = chi2_.makeFunction(false); result.model_.resize(v.size());
FitResult result; for (unsigned int j = 0; j < v.size(); ++j)
result = minimizer(chi2);
result.chi2_ = chi2(result);
result.nDof_ = chi2_.getNDof();
result.model_.resize(modelVector.size());
for (unsigned int j = 0; j < modelVector.size(); ++j)
{ {
result.model_[j] = modelVector[j]->fixPar(result); result.model_[j] = v[j]->fixPar(result);
}
for (Index p = 0; p < totalNPar; ++p)
{
result.parName_.push_back(chi2.varName().getName(p));
} }
return result; return result;
} }
// residuals /////////////////////////////////////////////////////////////////// FitResult XYStatData::fit(Minimizer &minimizer, const DVec &init,
XYStatData XYStatData::getResiduals(const FitResult &fit) const const vector<const DoubleModel *> &v)
{ {
XYStatData res(*this); vector<Minimizer *> mv{&minimizer};
for (Index j = 0; j < res.getYDim(); ++j) return fit(mv, init, v);
{
const DoubleFunction &f = fit.getModel(j);
for (Index k = 0; k < res.getNData(); ++k)
{
res.y(j, k) -= f(res.x(_, k).transpose());
}
}
return res;
} }
XYStatData XYStatData::getPartialResiduals(const FitResult &fit, const DVec &x, // residuals ///////////////////////////////////////////////////////////////////
const Index i) const XYStatData XYStatData::getResiduals(const FitResult &fit)
{ {
XYStatData res(*this); XYStatData res(*this);
DVec buf(x), xk;
for (Index j = 0; j < getNYDim(); ++j)
for (Index j = 0; j < res.getYDim(); ++j)
{ {
const DoubleFunction &f = fit.getModel(j); const DoubleFunction &f = fit.getModel(j);
for (Index k = 0; k < res.getNData(); ++k) for (auto &p: yData_[j])
{ {
buf(i) = res.x(i, k); res.y(p.first, j) -= f(x(p.first));
res.y(j, k) -= f(res.x(_, k).transpose()) - f(buf);
} }
} }
return res; return res;
} }
XYStatData XYStatData::getPartialResiduals(const FitResult &fit,
const DVec &ref, const Index i)
{
XYStatData res(*this);
DVec buf(ref);
for (Index j = 0; j < res.getNYDim(); ++j)
{
const DoubleFunction &f = fit.getModel(j);
for (auto &p: yData_[j])
{
buf(i) = x(p.first)(i);
res.y(p.first, j) -= f(x(p.first)) - f(buf);
}
}
return res;
}
// create data /////////////////////////////////////////////////////////////////
void XYStatData::createXData(const std::string name __dumb, const Index nData)
{
xData_.push_back(DVec::Zero(nData));
xBuf_.resize(xData_.size());
resizeVarMat();
}
void XYStatData::createYData(const std::string name __dumb)
{
yData_.push_back(map<Index, double>());
resizeVarMat();
}
void XYStatData::resizeVarMat(void)
{
xxVar_.conservativeResize(getNXDim(), getNXDim());
for (Index i1 = 0; i1 < getNXDim(); ++i1)
for (Index i2 = 0; i2 < getNXDim(); ++i2)
{
xxVar_(i1, i2).conservativeResize(getXSize(i1), getXSize(i2));
}
yyVar_.conservativeResize(getNYDim(), getNYDim());
for (Index j1 = 0; j1 < getNYDim(); ++j1)
for (Index j2 = 0; j2 < getNYDim(); ++j2)
{
yyVar_(j1, j2).conservativeResize(getYSize(j1), getYSize(j2));
}
xyVar_.conservativeResize(getNXDim(), getNYDim());
for (Index i = 0; i < getNXDim(); ++i)
for (Index j = 0; j < getNYDim(); ++j)
{
xyVar_(i, j).conservativeResize(getXSize(i), getYSize(j));
}
scheduleFitVarMatInit();
}
// schedule buffer computation /////////////////////////////////////////////////
void XYStatData::scheduleXMapInit(void)
{
initXMap_ = true;
}
void XYStatData::scheduleChi2DataVecInit(void)
{
initChi2DataVec_ = true;
}
// buffer total fit variance matrix ////////////////////////////////////////////
void XYStatData::updateFitVarMat(void)
{
if (initVarMat())
{
updateLayout();
DMat &v = fitVar_;
Index roffs, coffs;
v.resize(layout.totalSize, layout.totalSize);
roffs = layout.totalYSize;
for (Index ifit1 = 0; ifit1 < layout.nXFitDim; ++ifit1)
{
coffs = layout.totalYSize;
for (Index ifit2 = 0; ifit2 < layout.nXFitDim; ++ifit2)
{
for (Index rfit1 = 0; rfit1 < layout.xSize[ifit1]; ++rfit1)
for (Index rfit2 = 0; rfit2 < layout.xSize[ifit2]; ++rfit2)
{
Index i1, i2, r1, r2;
i1 = layout.xDim[ifit1];
i2 = layout.xDim[ifit2];
r1 = layout.x[ifit1][rfit1];
r2 = layout.x[ifit2][rfit2];
v(roffs+rfit1, coffs+rfit2) = xxVar_(i1, i2)(r1, r2);
v(coffs+rfit2, roffs+rfit1) = v(roffs+rfit1, coffs+rfit2);
}
coffs += layout.xSize[ifit2];
}
roffs += layout.xSize[ifit1];
}
roffs = 0;
for (Index jfit1 = 0; jfit1 < layout.nYFitDim; ++jfit1)
{
coffs = 0;
for (Index jfit2 = 0; jfit2 < layout.nYFitDim; ++jfit2)
{
for (Index sfit1 = 0; sfit1 < layout.ySize[jfit1]; ++sfit1)
for (Index sfit2 = 0; sfit2 < layout.ySize[jfit2]; ++sfit2)
{
Index j1, j2, s1, s2;
j1 = layout.yDim[jfit1];
j2 = layout.yDim[jfit2];
s1 = layout.y[jfit1][sfit1];
s2 = layout.y[jfit2][sfit2];
v(roffs+sfit1, coffs+sfit2) = yyVar_(j1, j2)(s1, s2);
v(coffs+sfit2, roffs+sfit1) = v(roffs+sfit1, coffs+sfit2);
}
coffs += layout.ySize[jfit2];
}
roffs += layout.ySize[jfit1];
}
roffs = layout.totalYSize;
for (Index ifit = 0; ifit < layout.nXFitDim; ++ifit)
{
coffs = 0;
for (Index jfit = 0; jfit < layout.nYFitDim; ++jfit)
{
for (Index rfit = 0; rfit < layout.xSize[ifit]; ++rfit)
for (Index sfit = 0; sfit < layout.ySize[jfit]; ++sfit)
{
Index i, j, r, s;
i = layout.xDim[ifit];
j = layout.yDim[jfit];
r = layout.x[ifit][rfit];
s = layout.y[jfit][sfit];
v(roffs+rfit, coffs+sfit) = xyVar_(i, j)(r, s);
v(coffs+sfit, roffs+rfit) = v(roffs+rfit, coffs+sfit);
}
coffs += layout.ySize[jfit];
}
roffs += layout.xSize[ifit];
}
chi2DataVec_.resize(layout.totalSize);
chi2ModVec_.resize(layout.totalSize);
chi2Vec_.resize(layout.totalSize);
fitVar_ = fitVar_.cwiseProduct(makeCorrFilter());
fitVarInv_ = fitVar_.pInverse(getSvdTolerance());
scheduleFitVarMatInit(false);
}
}
// buffer list of x vectors ////////////////////////////////////////////////////
void XYStatData::updateXMap(void) const
{
if (initXMap_)
{
XYStatData * modThis = const_cast<XYStatData *>(this);
modThis->xMap_.clear();
modThis->xMap_.resize(getMaxDataIndex());
for (auto k: getDataIndexSet())
{
modThis->xMap_[k] = DVec(getNXDim());
for (Index i = 0; i < getNXDim(); ++i)
{
modThis->xMap_[k](i) = xData_[i](dataCoord(k)[i]);
}
}
modThis->initXMap_ = false;
}
}
// buffer chi^2 vectors ////////////////////////////////////////////////////////
void XYStatData::updateChi2DataVec(void)
{
if (initChi2DataVec_)
{
Index a = 0, j, k, i, r;
updateLayout();
for (Index jfit = 0; jfit < layout.nYFitDim; ++jfit)
for (Index sfit = 0; sfit < layout.ySize[jfit]; ++sfit)
{
j = layout.yDim[jfit];
k = layout.data[jfit][sfit];
chi2DataVec_(a) = yData_[j][k];
a++;
}
for (Index ifit = 0; ifit < layout.nXFitDim; ++ifit)
for (Index rfit = 0; rfit < layout.xSize[ifit]; ++rfit)
{
i = layout.xDim[ifit];
r = layout.x[ifit][rfit];
chi2DataVec_(a) = xData_[i](r);
a++;
}
initChi2DataVec_ = false;
}
}
// WARNING: updateChi2ModVec is heavily called by fit
void XYStatData::updateChi2ModVec(const DVec p,
const vector<const DoubleModel *> &v,
const Index nPar, const Index nXDim)
{
updateLayout();
updateXMap();
Index a = 0, j, k, ind;
auto &par = p.segment(0, nPar), &xsi = p.segment(nPar, layout.totalXSize);
for (Index jfit = 0; jfit < layout.nYFitDim; ++jfit)
{
j = layout.yDim[jfit];
for (Index sfit = 0; sfit < layout.ySize[jfit]; ++sfit)
{
k = layout.data[jfit][sfit];
for (Index i = 0; i < nXDim; ++i)
{
ind = layout.xIndFromData[k][i] - layout.totalYSize;
xBuf_(i) = (ind >= 0) ? xsi(ind) : xMap_[k](i);
}
chi2ModVec_(a) = (*v[j])(xBuf_.data(), par.data());
a++;
}
}
chi2ModVec_.segment(a, layout.totalXSize) = xsi;
}

View File

@ -1,7 +1,7 @@
/* /*
* XYData.hpp, part of LatAnalyze 3 * XYStatData.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -17,17 +17,13 @@
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>. * along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef Latan_XYData_hpp_ #ifndef Latan_XYStatData_hpp_
#define Latan_XYData_hpp_ #define Latan_XYStatData_hpp_
#include <LatAnalyze/Global.hpp> #include <LatAnalyze/Global.hpp>
#include <LatAnalyze/Chi2Function.hpp>
#include <LatAnalyze/FitInterface.hpp> #include <LatAnalyze/FitInterface.hpp>
#include <LatAnalyze/Function.hpp>
#include <LatAnalyze/Mat.hpp>
#include <LatAnalyze/Minimizer.hpp> #include <LatAnalyze/Minimizer.hpp>
#include <LatAnalyze/Model.hpp> #include <LatAnalyze/Model.hpp>
#include <vector>
BEGIN_LATAN_NAMESPACE BEGIN_LATAN_NAMESPACE
@ -37,6 +33,7 @@ BEGIN_LATAN_NAMESPACE
class FitResult: public DVec class FitResult: public DVec
{ {
friend class XYStatData; friend class XYStatData;
friend class XYSampleData;
friend class SampleFitResult; friend class SampleFitResult;
public: public:
// constructors // constructors
@ -48,103 +45,192 @@ public:
double getChi2(void) const; double getChi2(void) const;
double getChi2PerDof(void) const; double getChi2PerDof(void) const;
double getNDof(void) const; double getNDof(void) const;
Index getNPar(void) const;
double getPValue(void) const; double getPValue(void) const;
const DoubleFunction & getModel(const Index j = 0) const; const DoubleFunction & getModel(const Index j = 0) const;
// IO
void print(const bool printXsi = false,
std::ostream &out = std::cout) const;
private: private:
double chi2_{0.0}; double chi2_{0.};
Index nDof_{0}; Index nDof_{0}, nPar_{0};
std::vector<DoubleFunction> model_; std::vector<DoubleFunction> model_;
std::vector<std::string> parName_;
}; };
/****************************************************************************** /******************************************************************************
* object for X vs. Y statistical data * * class for X vs. Y statistical data *
****************************************************************************** ******************************************************************************/
* index convention: i: X, j: Y, k: data
*/
class XYStatData: public FitInterface class XYStatData: public FitInterface
{ {
public: public:
enum // constructor
{ XYStatData(void) = default;
xx = 0,
yy = 1,
yx = 2
};
public:
// constructors
XYStatData(void);
XYStatData(const Index nData, const Index nXDim, const Index nYDim);
// destructor // destructor
virtual ~XYStatData(void) = default; virtual ~XYStatData(void) = default;
// access // data access
void resize(const Index nData, const Index xDim, double & x(const Index r, const Index i);
const Index yDim); const double & x(const Index r, const Index i) const;
void reinitChi2(const bool doReinit = true); const DVec & x(const Index k) const;
Block<MatBase<double>> x(const PlaceHolder ph1 = _, double & y(const Index k, const Index j);
const PlaceHolder ph2 = _); const double & y(const Index k, const Index j) const;
ConstBlock<MatBase<double>> x(const PlaceHolder ph1 = _, void setXXVar(const Index i1, const Index i2, const DMat &m);
const PlaceHolder ph2 = _) const; void setYYVar(const Index j1, const Index j2, const DMat &m);
Block<MatBase<double>> x(const Index i, const PlaceHolder ph2 = _); void setXYVar(const Index i, const Index j, const DMat &m);
ConstBlock<MatBase<double>> x(const Index i, void setXError(const Index i, const DVec &err);
const PlaceHolder ph2 = _) const; void setYError(const Index j, const DVec &err);
Block<MatBase<double>> x(const PlaceHolder ph1, const Index k); template <typename... Ts>
ConstBlock<MatBase<double>> x(const PlaceHolder ph1, void setUnidimData(const DMat &xData, const Ts & ...yDatas);
const Index k) const; const DMat & getXXVar(const Index i1, const Index i2) const;
double & x(const Index i, const Index k); const DMat & getYYVar(const Index j1, const Index j2) const;
const double & x(const Index i, const Index k) const; const DMat & getXYVar(const Index i, const Index j) const;
Block<MatBase<double>> y(const PlaceHolder ph1 = _, DVec getXError(const Index i) const;
const PlaceHolder ph2 = _); DVec getYError(const Index j) const;
ConstBlock<MatBase<double>> y(const PlaceHolder ph1 = _, DMat getTable(const Index i, const Index j) const;
const PlaceHolder ph2 = _) const; // get total fit variance matrix and its pseudo-inverse
Block<MatBase<double>> y(const Index i, const PlaceHolder ph2 = _); const DMat & getFitVarMat(void);
ConstBlock<MatBase<double>> y(const Index i, const DMat & getFitVarMatPInv(void);
const PlaceHolder ph2 = _) const;
Block<MatBase<double>> y(const PlaceHolder ph1, const Index k);
ConstBlock<MatBase<double>> y(const PlaceHolder ph1,
const Index k) const;
double & y(const Index i, const Index k);
const double & y(const Index i, const Index k) const;
Block<MatBase<double>> xxVar(const Index i1, const Index i2);
ConstBlock<MatBase<double>> xxVar(const Index i1, const Index i2) const;
Block<MatBase<double>> yyVar(const Index j1, const Index j2);
ConstBlock<MatBase<double>> yyVar(const Index j1, const Index j2) const;
Block<MatBase<double>> yxVar(const Index j, const Index i);
ConstBlock<MatBase<double>> yxVar(const Index j, const Index i) const;
// fit // fit
FitResult fit(std::vector<Minimizer *> &minimizer, const DVec &init,
const std::vector<const DoubleModel *> &v);
FitResult fit(Minimizer &minimizer, const DVec &init, FitResult fit(Minimizer &minimizer, const DVec &init,
const std::vector<const DoubleModel *> &modelVector); const std::vector<const DoubleModel *> &v);
template <typename... Ts>
FitResult fit(std::vector<Minimizer *> &minimizer, const DVec &init,
const DoubleModel &model, const Ts... models);
template <typename... Ts> template <typename... Ts>
FitResult fit(Minimizer &minimizer, const DVec &init, FitResult fit(Minimizer &minimizer, const DVec &init,
const DoubleModel &model, const Ts... models); const DoubleModel &model, const Ts... models);
// residuals // residuals
XYStatData getResiduals(const FitResult &fit) const; XYStatData getResiduals(const FitResult &fit);
XYStatData getPartialResiduals(const FitResult &fit, const DVec &x, XYStatData getPartialResiduals(const FitResult &fit, const DVec &ref,
const Index j) const; const Index i);
protected:
// create data
virtual void createXData(const std::string name, const Index nData);
virtual void createYData(const std::string name);
void resizeVarMat(void);
private: private:
DMat x_, y_; // schedule buffer computation
Mat<DMat> var_[3]; void scheduleXMapInit(void);
IVec isXExact_, isFitPoint_; void scheduleChi2DataVecInit(void);
Chi2Function chi2_; // buffer total fit variance matrix
bool reinitChi2_{true}; void updateFitVarMat(void);
// buffer list of x vectors
void updateXMap(void) const;
// buffer chi^2 vectors
void updateChi2DataVec(void);
void updateChi2ModVec(const DVec p,
const std::vector<const DoubleModel *> &v,
const Index nPar, const Index nXDim);
private:
std::vector<std::map<Index, double>> yData_;
// no map here for fit performance
std::vector<DVec> xData_;
std::vector<DVec> xMap_;
Mat<DMat> xxVar_, yyVar_, xyVar_;
DMat fitVar_, fitVarInv_;
DVec chi2DataVec_, chi2ModVec_, chi2Vec_;
DVec xBuf_;
bool initXMap_{true};
bool initChi2DataVec_{true};
}; };
/****************************************************************************** /******************************************************************************
* XYStatData template implementation * * XYStatData template implementation *
******************************************************************************/ ******************************************************************************/
template <typename... Ts> template <typename... Ts>
FitResult XYStatData::fit(Minimizer &minimizer, const DVec &init, void XYStatData::setUnidimData(const DMat &xData, const Ts & ...yDatas)
{
static_assert(static_or<std::is_assignable<DMat, Ts>::value...>::value,
"y data arguments are not compatible with DMat");
std::vector<const DMat *> yData{&yDatas...};
FOR_VEC(xData, r)
{
x(r, 0) = xData(r);
for (unsigned int j = 0; j < yData.size(); ++j)
{
y(r, j) = (*(yData[j]))(r);
}
}
}
template <typename... Ts>
FitResult XYStatData::fit(std::vector<Minimizer *> &minimizer, const DVec &init,
const DoubleModel &model, const Ts... models) const DoubleModel &model, const Ts... models)
{ {
static_assert(static_or<std::is_assignable<DoubleModel &, Ts>::value...>::value, static_assert(static_or<std::is_assignable<DoubleModel &, Ts>::value...>::value,
"model arguments are not compatible with DoubleModel &"); "model arguments are not compatible with DoubleModel");
std::vector<const DoubleModel *> modelVector{&model, &models...}; std::vector<const DoubleModel *> modelVector{&model, &models...};
return fit(minimizer, init, modelVector); return fit(minimizer, init, modelVector);
} }
template <typename... Ts>
FitResult XYStatData::fit(Minimizer &minimizer, const DVec &init,
const DoubleModel &model, const Ts... models)
{
static_assert(static_or<std::is_assignable<DoubleModel &, Ts>::value...>::value,
"model arguments are not compatible with DoubleModel");
std::vector<Minimizer *> mv{&minimizer};
return fit(mv, init, model, models...);
}
/******************************************************************************
* error check macros *
******************************************************************************/
#define checkVarMat(m, var)\
if (((m).rows() != (var).rows()) or ((m).cols() != (var).cols()))\
{\
LATAN_ERROR(Size, "provided variance matrix has a wrong size"\
" (expected " + strFrom((var).rows()) + "x"\
+ strFrom((var).cols()) + ", got " + strFrom((m).rows())\
+ "x" + strFrom((m).cols()) + ")");\
}
#define checkErrVec(err, var)\
if ((err).size() != (var).rows())\
{\
LATAN_ERROR(Size, "provided error vector has a wrong size"\
" (expected " + strFrom((var).rows()) + ", got "\
+ strFrom((err).size()) + ")");\
}
#define checkModelVec(v)\
if (static_cast<Index>((v).size()) != getNYDim())\
{\
LATAN_ERROR(Size, "provided model vector has a wrong size"\
" (expected " + strFrom(getNYDim()) + ", got "\
+ strFrom((v).size()) + ")");\
}\
for (unsigned int _i = 1; _i < (v).size(); ++_i)\
{\
if ((v)[_i]->getNArg() != getNXDim())\
{\
LATAN_ERROR(Size, "model " + strFrom(_i) + " has a wrong"\
+ " number of argument (expected " + strFrom(getNXDim())\
+ ", got " + strFrom((v)[_i]->getNArg()));\
}\
}\
{\
Index _nPar = (v)[0]->getNPar();\
for (unsigned int _i = 1; _i < (v).size(); ++_i)\
{\
if ((v)[_i]->getNPar() != _nPar)\
{\
LATAN_ERROR(Size, "model " + strFrom(_i) + " has a wrong"\
+ " number of parameter (expected " + strFrom(_nPar)\
+ ", got " + strFrom((v)[_i]->getNPar()));\
}\
}\
}
END_LATAN_NAMESPACE END_LATAN_NAMESPACE
#endif // Latan_XYData_hpp_ #endif // Latan_XYStatData_hpp_

View File

@ -1,7 +1,7 @@
/* /*
* includes.hpp, part of LatAnalyze 3 * includes.hpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -20,23 +20,6 @@
#ifndef Latan_includes_hpp_ #ifndef Latan_includes_hpp_
#define Latan_includes_hpp_ #define Latan_includes_hpp_
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <sstream>
#include <utility>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include <sys/stat.h>
#include <unistd.h>
#include <config.h> #include <config.h>
#endif // Latan_includes_hpp_ #endif // Latan_includes_hpp_

View File

@ -1,30 +1,18 @@
if CC_GNU
COM_CFLAGS = -Wall -W -pedantic
else
if CC_INTEL
COM_CFLAGS = -Wall
endif
endif
if CXX_GNU if CXX_GNU
COM_CXXFLAGS = -Wall -W -pedantic COM_CXXFLAGS = -Wall -W -pedantic -Wno-deprecated-declarations
else else
if CXX_INTEL if CXX_INTEL
COM_CXXFLAGS = -Wall COM_CXXFLAGS = -wd1682 -Wall
endif endif
endif endif
bin_PROGRAMS = \ bin_PROGRAMS = \
latan_create_rg_state \
latan_make_fake_sample\ latan_make_fake_sample\
latan_sample_combine \ latan_sample_combine \
latan_sample_plot_corr\
latan_sample_read \ latan_sample_read \
latan_resample latan_resample
latan_create_rg_state_SOURCES = create_rg_state.cpp
latan_create_rg_state_CXXFLAGS = $(COM_CXXFLAGS)
latan_create_rg_state_LDFLAGS = -L../lib/.libs -lLatAnalyze
latan_make_fake_sample_SOURCES = make_fake_sample.cpp latan_make_fake_sample_SOURCES = make_fake_sample.cpp
latan_make_fake_sample_CXXFLAGS = $(COM_CXXFLAGS) latan_make_fake_sample_CXXFLAGS = $(COM_CXXFLAGS)
latan_make_fake_sample_LDFLAGS = -L../lib/.libs -lLatAnalyze latan_make_fake_sample_LDFLAGS = -L../lib/.libs -lLatAnalyze
@ -33,6 +21,10 @@ latan_sample_combine_SOURCES = sample_combine.cpp
latan_sample_combine_CXXFLAGS = $(COM_CXXFLAGS) latan_sample_combine_CXXFLAGS = $(COM_CXXFLAGS)
latan_sample_combine_LDFLAGS = -L../lib/.libs -lLatAnalyze latan_sample_combine_LDFLAGS = -L../lib/.libs -lLatAnalyze
latan_sample_plot_corr_SOURCES = sample_plot_corr.cpp
latan_sample_plot_corr_CXXFLAGS = $(COM_CXXFLAGS)
latan_sample_plot_corr_LDFLAGS = -L../lib/.libs -lLatAnalyze
latan_sample_read_SOURCES = sample_read.cpp latan_sample_read_SOURCES = sample_read.cpp
latan_sample_read_CXXFLAGS = $(COM_CXXFLAGS) latan_sample_read_CXXFLAGS = $(COM_CXXFLAGS)
latan_sample_read_LDFLAGS = -L../lib/.libs -lLatAnalyze latan_sample_read_LDFLAGS = -L../lib/.libs -lLatAnalyze

View File

@ -1,7 +1,7 @@
/* /*
* make_fake_sample.cpp, part of LatAnalyze 3 * make_fake_sample.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -17,9 +17,7 @@
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>. * along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <iostream>
#include <LatAnalyze/Io.hpp> #include <LatAnalyze/Io.hpp>
#include <LatAnalyze/RandGen.hpp>
using namespace std; using namespace std;
using namespace Latan; using namespace Latan;
@ -42,21 +40,23 @@ int main(int argc, char *argv[])
nSample = strTo<Index>(argv[3]); nSample = strTo<Index>(argv[3]);
outFileName = argv[4]; outFileName = argv[4];
RandGen gen; random_device rd;
DMatSample res(nSample, 1, 1); mt19937 gen(rd());
normal_distribution<> dis(val, err);
DSample res(nSample);
FOR_STAT_ARRAY(res, s) FOR_STAT_ARRAY(res, s)
{ {
if (s == central) if (s == central)
{ {
res[s](0, 0) = val; res[s] = val;
} }
else else
{ {
res[s](0, 0) = gen.gaussian(val, err); res[s] = dis(gen);
} }
} }
Io::save<DMatSample>(res, outFileName); Io::save<DSample>(res, outFileName);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -1,7 +1,7 @@
/* /*
* resample.cpp, part of LatAnalyze 3 * resample.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -17,10 +17,6 @@
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>. * along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <iostream>
#include <map>
#include <libgen.h>
#include <unistd.h>
#include <LatAnalyze/Dataset.hpp> #include <LatAnalyze/Dataset.hpp>
#include <LatAnalyze/Io.hpp> #include <LatAnalyze/Io.hpp>
@ -34,7 +30,7 @@ using namespace Latan;
static void usage(const string &cmdName) static void usage(const string &cmdName)
{ {
cerr << "usage: " << cmdName; cerr << "usage: " << cmdName;
cerr << " [-n <nsample> -b <bin size> -r <state> -o <output dir> -f {h5|sample}]"; cerr << " [-n <nsample> -b <bin size> -r <seed> -o <output dir> -f {h5|sample}]";
cerr << " <data list> <name list>"; cerr << " <data list> <name list>";
cerr << endl; cerr << endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -43,10 +39,12 @@ static void usage(const string &cmdName)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// argument parsing //////////////////////////////////////////////////////// // argument parsing ////////////////////////////////////////////////////////
int c; int c;
string manFileName, nameFileName, stateFileName, cmdName, outDirName = "."; random_device rd;
string ext = "h5"; SeedType seed = rd();
Index binSize = 1, nSample = DEF_NSAMPLE; string manFileName, nameFileName, cmdName, outDirName = ".";
string ext = "h5";
Index binSize = 1, nSample = DEF_NSAMPLE;
opterr = 0; opterr = 0;
cmdName = basename(argv[0]); cmdName = basename(argv[0]);
@ -64,7 +62,7 @@ int main(int argc, char *argv[])
outDirName = optarg; outDirName = optarg;
break; break;
case 'r': case 'r':
stateFileName = optarg; seed = strTo<SeedType>(optarg);
break; break;
case 'f': case 'f':
ext = optarg; ext = optarg;
@ -126,25 +124,15 @@ int main(int argc, char *argv[])
// data resampling ///////////////////////////////////////////////////////// // data resampling /////////////////////////////////////////////////////////
DMatSample s(nSample); DMatSample s(nSample);
RandGen g;
RandGenState state;
cout << "-- resampling data..." << endl; cout << "-- resampling data..." << endl;
if (!stateFileName.empty())
{
state = Io::load<RandGenState>(stateFileName);
}
for (unsigned int i = 0; i < name.size(); ++i) for (unsigned int i = 0; i < name.size(); ++i)
{ {
const string outFileName = name[i] + "_" + manFileName + "." + ext; const string outFileName = name[i] + "_" + manFileName + "." + ext;
cout << '\r' << ProgressBar(i + 1, name.size()); cout << '\r' << ProgressBar(i + 1, name.size());
data[name[i]].bin(binSize); data[name[i]].bin(binSize);
if (!stateFileName.empty()) s = data[name[i]].bootstrapMean(nSample, seed);
{
g.setState(state);
}
s = data[name[i]].bootstrapMean(nSample, g);
Io::save<DMatSample>(s, outDirName + "/" + outFileName, Io::save<DMatSample>(s, outDirName + "/" + outFileName,
File::Mode::write, outFileName); File::Mode::write, outFileName);
} }

View File

@ -1,7 +1,7 @@
/* /*
* sample_combine.cpp, part of LatAnalyze 3 * sample_combine.cpp, part of LatAnalyze 3
* *
* Copyright (C) 2013 - 2015 Antonin Portelli * Copyright (C) 2013 - 2016 Antonin Portelli
* *
* LatAnalyze 3 is free software: you can redistribute it and/or modify * LatAnalyze 3 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -17,9 +17,6 @@
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>. * along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <iostream>
#include <libgen.h>
#include <unistd.h>
#include <LatAnalyze/Io.hpp> #include <LatAnalyze/Io.hpp>
#include <LatAnalyze/CompiledFunction.hpp> #include <LatAnalyze/CompiledFunction.hpp>
@ -35,6 +32,108 @@ static void usage(const string &cmdName)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
template <typename T>
static void loadAndCheck(vector<T> &sample, const vector<string> &fileName)
{
const unsigned int n = sample.size();
Index nSample = 0;
cout << "-- loading data..." << endl;
for (unsigned int i = 0; i < n; ++i)
{
sample[i] = Io::load<T>(fileName[i]);
if (i == 0)
{
nSample = sample[i].size();
}
else if (sample[i].size() != nSample)
{
cerr << "error: number of sample mismatch (between '";
cerr << fileName[0] << "' and '" << fileName[i] << "')" << endl;
abort();
}
}
}
template <typename T>
static void combine(const string &outFileName __dumb,
const vector<T> &sample __dumb, const string &code __dumb)
{
abort();
}
template <>
void combine(const string &outFileName, const vector<DSample> &sample,
const string &code)
{
const unsigned int n = sample.size();
DoubleFunction f = compile(code, n);
DSample result(sample[0]);
DVec buf(n);
cout << "-- combining data..." << endl;
result = sample[0];
FOR_STAT_ARRAY(result, s)
{
for (unsigned int k = 0; k < n; ++k)
{
buf[k] = sample[k][s];
}
result[s] = f(buf);
}
cout << scientific;
cout << "central value:\n" << result[central];
cout << endl;
cout << "standard deviation:\n" << sqrt(result.variance());
cout << endl;
if (!outFileName.empty())
{
Io::save<DSample>(result, outFileName);
}
}
template <>
void combine(const string &outFileName, const vector<DMatSample> &sample,
const string &code)
{
const unsigned int n = sample.size();
DoubleFunction f = compile(code, n);
DVec buf(n);
DMatSample result(sample[0]);
cout << "-- combining data..." << endl;
FOR_STAT_ARRAY(result, s)
{
FOR_MAT(result[s], i, j)
{
for (unsigned int k = 0; k < n; ++k)
{
buf[k] = sample[k][s](i,j);
}
result[s](i, j) = f(buf);
}
}
cout << scientific;
cout << "central value:\n" << result[central];
cout << endl;
cout << "standard deviation:\n" << result.variance().cwiseSqrt();
cout << endl;
if (!outFileName.empty())
{
Io::save<DMatSample>(result, outFileName);
}
}
template <typename T>
void process(const string &outFileName, const vector<string> &fileName,
const string &code)
{
vector<T> sample(fileName.size());
loadAndCheck(sample, fileName);
combine(outFileName, sample, code);
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// argument parsing //////////////////////////////////////////////////////// // argument parsing ////////////////////////////////////////////////////////
@ -82,54 +181,16 @@ int main(int argc, char *argv[])
{ {
usage(cmdName); usage(cmdName);
} }
// data loading //////////////////////////////////////////////////////////// // process data ////////////////////////////////////////////////////////////
vector<DMatSample> sample(n); try
Index nSample = 0;
cout << "-- loading data..." << endl;
for (unsigned int i = 0; i < n; ++i)
{ {
sample[i] = Io::load<DMatSample>(fileName[i]); process<DSample>(outFileName, fileName, code);
if (i == 0)
{
nSample = sample[i].size();
}
else if (sample[i].size() != nSample)
{
cerr << "error: number of sample mismatch (between '";
cerr << fileName[0] << "' and '" << fileName[i] << "')" << endl;
return EXIT_FAILURE;
}
} }
catch (bad_cast &e)
// combine data ////////////////////////////////////////////////////////////
DoubleFunction f = compile(code, n);
DVec buf(n);
DMatSample result(sample[0]);
cout << "-- combining data..." << endl;
FOR_STAT_ARRAY(result, s)
{ {
FOR_MAT(result[s], i, j) process<DMatSample>(outFileName, fileName, code);
{
for (unsigned int k = 0; k < n; ++k)
{
buf[k] = sample[k][s](i,j);
}
result[s](i, j) = f(buf);
}
} }
// output //////////////////////////////////////////////////////////////////
cout << scientific;
cout << "central value:\n" << result[central] << endl;
cout << "standard deviation:\n" << result.variance().cwiseSqrt() << endl;
if (!outFileName.empty())
{
Io::save<DMatSample>(result, outFileName);
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

Some files were not shown because too many files have changed in this diff Show More