mirror of
https://github.com/aportelli/LatAnalyze.git
synced 2025-04-11 03:20:46 +01:00
Merge from AP's develop.
This commit is contained in:
commit
cd1aeac669
26
.github/workflows/build-macos.yml
vendored
Normal file
26
.github/workflows/build-macos.yml
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
name: Build macOS
|
||||||
|
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: macos-11
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Install basic dependencies
|
||||||
|
run: brew install automake autoconf libtool bison flex
|
||||||
|
- name: Build dependencies
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
export PATH=/usr/local/opt/flex/bin:/usr/local/opt/bison/bin:${PATH}
|
||||||
|
cd ci-scripts
|
||||||
|
./install-deps.sh prefix 6
|
||||||
|
- name: Build LatAnalyze
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
export PATH=/usr/local/opt/flex/bin:/usr/local/opt/bison/bin:${PATH}
|
||||||
|
cd ci-scripts
|
||||||
|
./install-latan.sh prefix 6
|
26
.github/workflows/build-ubuntu.yml
vendored
Normal file
26
.github/workflows/build-ubuntu.yml
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
name: Build Ubuntu
|
||||||
|
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Install basic dependencies
|
||||||
|
run: |
|
||||||
|
sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
|
||||||
|
sudo apt install cmake bison flex
|
||||||
|
- name: Build dependencies
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd ci-scripts
|
||||||
|
CC=clang CXX=clang++ ./install-deps.sh prefix 6
|
||||||
|
- name: Build LatAnalyze
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd ci-scripts
|
||||||
|
CC=clang CXX=clang++ ./install-latan.sh prefix 6
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -16,6 +16,7 @@ autom4te.cache/*
|
|||||||
*.in~
|
*.in~
|
||||||
config.h*
|
config.h*
|
||||||
configure
|
configure
|
||||||
|
configure~
|
||||||
.buildutils/*
|
.buildutils/*
|
||||||
aclocal.m4
|
aclocal.m4
|
||||||
|
|
||||||
|
19
Readme.md
19
Readme.md
@ -1,21 +1,6 @@
|
|||||||
# LatAnalyze
|
# LatAnalyze
|
||||||
|
|
||||||
License: GNU General Public License v3
|
[](https://www.gnu.org/licenses/gpl-3.0) [](https://zenodo.org/badge/latestdoi/10201777)
|
||||||
|
|
||||||
<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
|
## Description
|
||||||
LatAnalyze is a C++11 library for statistical data analysis based on bootstrap
|
LatAnalyze is a C++11 library for statistical data analysis based on bootstrap
|
||||||
@ -164,4 +149,4 @@ Fixes:
|
|||||||
#### v3.0
|
#### v3.0
|
||||||
Commit `7b4f2884a5e99bbfab4d4bd7623f609a55403c39`.
|
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.
|
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.**
|
**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.**
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
if (( $# != 1 )); then
|
if (( $# != 2 )); then
|
||||||
echo "usage: `basename $0` <prefix>" 1>&2
|
echo "usage: `basename $0` <prefix> <ntasks>" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
PREFIX=$1
|
PREFIX=$1
|
||||||
|
NTASKS=$2
|
||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
mkdir -p local/build
|
mkdir -p local/build
|
||||||
for d in gsl nlopt minuit hdf5; do
|
for d in gsl nlopt minuit hdf5; do
|
||||||
if [ ! -e local/.built.${d} ]; then
|
if [ ! -e local/.built.${d} ]; then
|
||||||
./install-${d}.sh ${PREFIX}
|
./install-${d}.sh ${PREFIX} ${NTASKS}
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
@ -2,11 +2,12 @@
|
|||||||
|
|
||||||
NAME='gsl-2.6'
|
NAME='gsl-2.6'
|
||||||
|
|
||||||
if (( $# != 1 )); then
|
if (( $# != 2 )); then
|
||||||
echo "usage: `basename $0` <prefix>" 1>&2
|
echo "usage: `basename $0` <prefix> <ntasks>" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
PREFIX=$1
|
PREFIX=$1
|
||||||
|
NTASKS=$2
|
||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
INITDIR=$(pwd -P)
|
INITDIR=$(pwd -P)
|
||||||
@ -19,7 +20,7 @@ tar -xzvf ${NAME}.tar.gz
|
|||||||
mkdir -p ${NAME}/build
|
mkdir -p ${NAME}/build
|
||||||
cd ${NAME}/build
|
cd ${NAME}/build
|
||||||
../configure --prefix=${PREFIX}
|
../configure --prefix=${PREFIX}
|
||||||
make -j4
|
make -j${NTASKS}
|
||||||
make install
|
make install
|
||||||
cd ${INITDIR}/local
|
cd ${INITDIR}/local
|
||||||
touch .built.gsl
|
touch .built.gsl
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
NAME='hdf5-1.10.5'
|
NAME='hdf5-1.10.8'
|
||||||
|
|
||||||
if (( $# != 1 )); then
|
if (( $# != 2 )); then
|
||||||
echo "usage: `basename $0` <prefix>" 1>&2
|
echo "usage: `basename $0` <prefix> <ntasks>" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
PREFIX=$1
|
PREFIX=$1
|
||||||
|
NTASKS=$2
|
||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
INITDIR=$(pwd -P)
|
INITDIR=$(pwd -P)
|
||||||
@ -19,7 +20,7 @@ tar -xzvf ${NAME}.tar.gz
|
|||||||
mkdir ${NAME}/build
|
mkdir ${NAME}/build
|
||||||
cd ${NAME}/build
|
cd ${NAME}/build
|
||||||
../configure --prefix=${PREFIX} --enable-cxx
|
../configure --prefix=${PREFIX} --enable-cxx
|
||||||
make -j4
|
make -j${NTASKS}
|
||||||
make install
|
make install
|
||||||
cd ${INITDIR}/local
|
cd ${INITDIR}/local
|
||||||
touch .built.hdf5
|
touch .built.hdf5
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
if (( $# != 1 )); then
|
if (( $# != 2 )); then
|
||||||
echo "usage: `basename $0` <prefix>" 1>&2
|
echo "usage: `basename $0` <prefix> <ntasks>" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
PREFIX=$1
|
PREFIX=$1
|
||||||
|
NTASKS=$2
|
||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
INITDIR=$(pwd -P)
|
INITDIR=$(pwd -P)
|
||||||
@ -12,11 +13,11 @@ mkdir -p ${PREFIX}
|
|||||||
cd ${PREFIX}
|
cd ${PREFIX}
|
||||||
PREFIX=$(pwd -P)
|
PREFIX=$(pwd -P)
|
||||||
cd ${INITDIR}
|
cd ${INITDIR}
|
||||||
./install-deps.sh ${PREFIX}
|
./install-deps.sh ${PREFIX} ${NTASKS}
|
||||||
cd ..
|
cd ..
|
||||||
./bootstrap.sh
|
./bootstrap.sh
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
cd build
|
cd build
|
||||||
../configure --prefix=${PREFIX} --with-minuit=${PREFIX} --with-nlopt=${PREFIX} --with-hdf5=${PREFIX} --with-gsl=${PREFIX} CXXFLAGS="${CXXFLAGS} -O3 -march=haswell -mtune=haswell"
|
../configure --prefix=${PREFIX} --with-minuit=${PREFIX} --with-nlopt=${PREFIX} --with-hdf5=${PREFIX} --with-gsl=${PREFIX} CXXFLAGS="${CXXFLAGS} -O3 -march=native -mtune=native"
|
||||||
make -j4
|
make -j${NTASKS}
|
||||||
make install
|
make install
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
NAME='Minuit2-5.34.14'
|
|
||||||
|
|
||||||
if (( $# != 1 )); then
|
if (( $# != 2 )); then
|
||||||
echo "usage: `basename $0` <prefix>" 1>&2
|
echo "usage: `basename $0` <prefix> <ntasks>" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
PREFIX=$1
|
PREFIX=$1
|
||||||
|
NTASKS=$2
|
||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
INITDIR=$(pwd -P)
|
INITDIR=$(pwd -P)
|
||||||
@ -14,12 +14,12 @@ mkdir -p ${PREFIX}
|
|||||||
cd ${PREFIX}
|
cd ${PREFIX}
|
||||||
PREFIX=$(pwd -P)
|
PREFIX=$(pwd -P)
|
||||||
cd ${INITDIR}/local/build
|
cd ${INITDIR}/local/build
|
||||||
wget http://www.cern.ch/mathlibs/sw/5_34_14/Minuit2/${NAME}.tar.gz
|
rm -rf root
|
||||||
tar -xzvf ${NAME}.tar.gz
|
git clone https://github.com/root-project/root.git
|
||||||
mkdir -p ${NAME}/build
|
cd root/math/minuit2/
|
||||||
cd ${NAME}/build
|
mkdir build; cd build
|
||||||
../configure --prefix=${PREFIX} --disable-openmp
|
cmake .. -Dminuit2_standalone=ON -DCMAKE_INSTALL_PREFIX=${PREFIX}
|
||||||
make -j4
|
make -j${NTASKS}
|
||||||
make install
|
make install
|
||||||
cd ${INITDIR}/local
|
cd ${INITDIR}/local
|
||||||
touch .built.minuit
|
touch .built.minuit
|
||||||
|
@ -2,11 +2,12 @@
|
|||||||
|
|
||||||
NAME='2.6.1'
|
NAME='2.6.1'
|
||||||
|
|
||||||
if (( $# != 1 )); then
|
if (( $# != 2 )); then
|
||||||
echo "usage: `basename $0` <prefix>" 1>&2
|
echo "usage: `basename $0` <prefix> <ntasks>" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
PREFIX=$1
|
PREFIX=$1
|
||||||
|
NTASKS=$2
|
||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
INITDIR=$(pwd -P)
|
INITDIR=$(pwd -P)
|
||||||
@ -20,7 +21,7 @@ NAME=nlopt-${NAME}
|
|||||||
mkdir -p ${NAME}/build
|
mkdir -p ${NAME}/build
|
||||||
cd ${NAME}/build
|
cd ${NAME}/build
|
||||||
cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} -DCMAKE_BUILD_WITH_INSTALL_NAME_DIR=TRUE -DCMAKE_INSTALL_NAME_DIR="${PREFIX}/lib" ..
|
cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} -DCMAKE_BUILD_WITH_INSTALL_NAME_DIR=TRUE -DCMAKE_INSTALL_NAME_DIR="${PREFIX}/lib" ..
|
||||||
make -j4
|
make -j${NTASKS}
|
||||||
make install
|
make install
|
||||||
cd ${INITDIR}/local
|
cd ${INITDIR}/local
|
||||||
touch .built.nlopt
|
touch .built.nlopt
|
||||||
|
23
configure.ac
23
configure.ac
@ -36,7 +36,7 @@ AC_ARG_WITH([gsl],
|
|||||||
AC_ARG_WITH([minuit],
|
AC_ARG_WITH([minuit],
|
||||||
[AS_HELP_STRING([--with-minuit=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_CXXFLAGS="$AM_CXXFLAGS -I$with_minuit/include"]
|
[AM_CXXFLAGS="$AM_CXXFLAGS -I$with_minuit/include -I$with_minuit/include/Minuit2 -I$with_minuit/include/Fit"]
|
||||||
[AM_LDFLAGS="$AM_LDFLAGS -L$with_minuit/lib"])
|
[AM_LDFLAGS="$AM_LDFLAGS -L$with_minuit/lib"])
|
||||||
AC_ARG_WITH([nlopt],
|
AC_ARG_WITH([nlopt],
|
||||||
[AS_HELP_STRING([--with-nlopt=prefix],
|
[AS_HELP_STRING([--with-nlopt=prefix],
|
||||||
@ -74,6 +74,7 @@ CXXFLAGS_CPY=$CXXFLAGS
|
|||||||
LDFLAGS_CPY=$LDFLAGS
|
LDFLAGS_CPY=$LDFLAGS
|
||||||
CXXFLAGS="$AM_CXXFLAGS $CXXFLAGS"
|
CXXFLAGS="$AM_CXXFLAGS $CXXFLAGS"
|
||||||
LDFLAGS="$AM_LDFLAGS $LDFLAGS"
|
LDFLAGS="$AM_LDFLAGS $LDFLAGS"
|
||||||
|
AC_CHECK_LIB([pthread],[pthread_create],[],[AC_MSG_ERROR([pthread library not found])])
|
||||||
AC_CHECK_LIB([m],[cos],[],[AC_MSG_ERROR([libm library not found])])
|
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])])
|
||||||
@ -90,10 +91,10 @@ AC_CHECK_LIB([hdf5_cpp],[H5Fopen],
|
|||||||
[AC_MSG_ERROR([HDF5 library not found])], [-lhdf5])
|
[AC_MSG_ERROR([HDF5 library not found])], [-lhdf5])
|
||||||
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::VariableMetricMinimizer in -lMinuit2]);
|
||||||
AC_LINK_IFELSE(
|
AC_LINK_IFELSE(
|
||||||
[AC_LANG_PROGRAM([#include <Minuit2/BasicMinimumError.h>],
|
[AC_LANG_PROGRAM([#include <Minuit2/VariableMetricMinimizer.h>],
|
||||||
[ROOT::Minuit2::BasicMinimumError dummy(0)])],
|
[ROOT::Minuit2::VariableMetricMinimizer dummy()])],
|
||||||
[LIBS="$LIBS -lMinuit2"]
|
[LIBS="$LIBS -lMinuit2"]
|
||||||
[AC_DEFINE([HAVE_MINUIT2],
|
[AC_DEFINE([HAVE_MINUIT2],
|
||||||
[1],
|
[1],
|
||||||
@ -103,6 +104,20 @@ AC_LINK_IFELSE(
|
|||||||
[have_minuit=false]
|
[have_minuit=false]
|
||||||
[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="$LDFLAGS -lMinuit2Math"
|
||||||
|
AC_MSG_CHECKING([for ROOT::Math::MinimizerOptions in -lMinuit2Math]);
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM([#include <Minuit2/Math/MinimizerOptions.h>],
|
||||||
|
[ROOT::Math::MinimizerOptions dummy()])],
|
||||||
|
[LIBS="$LIBS -lMinuit2Math"]
|
||||||
|
[AC_DEFINE([HAVE_MINUIT2MATH],
|
||||||
|
[1],
|
||||||
|
[Define to 1 if you have the `Minuit2Math' library (-lMinuit2Math).])]
|
||||||
|
[have_minuitmath=true]
|
||||||
|
[AC_MSG_RESULT([yes])],
|
||||||
|
[have_minuitmath=false]
|
||||||
|
[AC_MSG_RESULT([no])])
|
||||||
|
AM_CONDITIONAL([HAVE_MINUITMATH], [test x$have_minuit = xtrue])
|
||||||
LDFLAGS=$SAVED_LDFLAGS
|
LDFLAGS=$SAVED_LDFLAGS
|
||||||
CXXFLAGS=$CXXFLAGS_CPY
|
CXXFLAGS=$CXXFLAGS_CPY
|
||||||
LDFLAGS=$LDFLAGS_CPY
|
LDFLAGS=$LDFLAGS_CPY
|
||||||
|
@ -19,7 +19,8 @@ noinst_PROGRAMS = \
|
|||||||
exPlot \
|
exPlot \
|
||||||
exPValue \
|
exPValue \
|
||||||
exRand \
|
exRand \
|
||||||
exRootFinder
|
exRootFinder \
|
||||||
|
exThreadPool
|
||||||
|
|
||||||
exCompiledDoubleFunction_SOURCES = exCompiledDoubleFunction.cpp
|
exCompiledDoubleFunction_SOURCES = exCompiledDoubleFunction.cpp
|
||||||
exCompiledDoubleFunction_CXXFLAGS = $(COM_CXXFLAGS)
|
exCompiledDoubleFunction_CXXFLAGS = $(COM_CXXFLAGS)
|
||||||
@ -73,4 +74,8 @@ exRootFinder_SOURCES = exRootFinder.cpp
|
|||||||
exRootFinder_CXXFLAGS = $(COM_CXXFLAGS)
|
exRootFinder_CXXFLAGS = $(COM_CXXFLAGS)
|
||||||
exRootFinder_LDFLAGS = -L../lib/.libs -lLatAnalyze
|
exRootFinder_LDFLAGS = -L../lib/.libs -lLatAnalyze
|
||||||
|
|
||||||
|
exThreadPool_SOURCES = exThreadPool.cpp
|
||||||
|
exThreadPool_CXXFLAGS = $(COM_CXXFLAGS)
|
||||||
|
exThreadPool_LDFLAGS = -L../lib/.libs -lLatAnalyze
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS = -I .buildutils/m4
|
ACLOCAL_AMFLAGS = -I .buildutils/m4
|
||||||
|
29
examples/exThreadPool.cpp
Normal file
29
examples/exThreadPool.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include <LatAnalyze/Core/ThreadPool.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Latan;
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
ThreadPool pool;
|
||||||
|
|
||||||
|
cout << "Using " << pool.getThreadNum() << " threads" << endl;
|
||||||
|
for (unsigned int i = 1; i <= 20; ++i)
|
||||||
|
{
|
||||||
|
pool.addJob([i, &pool](void)
|
||||||
|
{
|
||||||
|
pool.critical([i](void)
|
||||||
|
{
|
||||||
|
cout << "job " << i << " wait for " << i*100 << " ms" << endl;
|
||||||
|
});
|
||||||
|
this_thread::sleep_for(chrono::milliseconds(i*100));
|
||||||
|
pool.critical([i](void)
|
||||||
|
{
|
||||||
|
cout << "job " << i << " done" << endl;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
pool.terminate();
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
@ -17,7 +17,7 @@
|
|||||||
* along with LatAnalyze. If not, see <http://www.gnu.org/licenses/>.
|
* along with LatAnalyze. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Derived pInverse(const double tolerance = 1.0e-10)
|
Derived pInverse(const double tolerance = 1.0e-10) const
|
||||||
{
|
{
|
||||||
auto svd = jacobiSvd(Eigen::ComputeThinU|Eigen::ComputeThinV);
|
auto svd = jacobiSvd(Eigen::ComputeThinU|Eigen::ComputeThinV);
|
||||||
const auto u = svd.matrixU();
|
const auto u = svd.matrixU();
|
||||||
@ -52,7 +52,7 @@ Derived pInverse(const double tolerance = 1.0e-10)
|
|||||||
return v*s.asDiagonal()*u.transpose();
|
return v*s.asDiagonal()*u.transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Derived singularValues(void)
|
Derived singularValues(void) const
|
||||||
{
|
{
|
||||||
auto svd = jacobiSvd();
|
auto svd = jacobiSvd();
|
||||||
|
|
||||||
|
@ -29,7 +29,8 @@ using namespace Latan;
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
DMat MATH_NAMESPACE::varToCorr(const DMat &var)
|
DMat MATH_NAMESPACE::varToCorr(const DMat &var)
|
||||||
{
|
{
|
||||||
DMat res = var, invDiag = res.diagonal();
|
DMat res = var;
|
||||||
|
DVec invDiag = res.diagonal();
|
||||||
|
|
||||||
invDiag = invDiag.cwiseInverse().cwiseSqrt();
|
invDiag = invDiag.cwiseInverse().cwiseSqrt();
|
||||||
res = (invDiag*invDiag.transpose()).cwiseProduct(res);
|
res = (invDiag*invDiag.transpose()).cwiseProduct(res);
|
||||||
@ -37,6 +38,28 @@ DMat MATH_NAMESPACE::varToCorr(const DMat &var)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DMat MATH_NAMESPACE::corrToVar(const DMat &corr, const DVec &varDiag)
|
||||||
|
{
|
||||||
|
DMat res = corr;
|
||||||
|
DVec varSqrtDiag = varDiag.cwiseSqrt();
|
||||||
|
|
||||||
|
res = (varSqrtDiag*varSqrtDiag.transpose()).cwiseProduct(res);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
double MATH_NAMESPACE::svdDynamicRange(const DMat &mat)
|
||||||
|
{
|
||||||
|
DVec s = mat.singularValues();
|
||||||
|
|
||||||
|
return s.maxCoeff()/s.minCoeff();
|
||||||
|
}
|
||||||
|
|
||||||
|
double MATH_NAMESPACE::svdDynamicRangeDb(const DMat &mat)
|
||||||
|
{
|
||||||
|
return 10.*log10(svdDynamicRange(mat));
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Standard C functions *
|
* Standard C functions *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -70,6 +70,11 @@ namespace MATH_NAMESPACE
|
|||||||
|
|
||||||
// convert variance matrix to correlation matrix
|
// convert variance matrix to correlation matrix
|
||||||
DMat varToCorr(const DMat &var);
|
DMat varToCorr(const DMat &var);
|
||||||
|
DMat corrToVar(const DMat &corr, const DVec &varDiag);
|
||||||
|
|
||||||
|
// matrix SVD dynamic range
|
||||||
|
double svdDynamicRange(const DMat &mat);
|
||||||
|
double svdDynamicRangeDb(const DMat &mat);
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
constexpr double pi = 3.1415926535897932384626433832795028841970;
|
constexpr double pi = 3.1415926535897932384626433832795028841970;
|
||||||
|
@ -112,7 +112,7 @@ PlotHeadCommand::PlotHeadCommand(const string &command)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PlotData constructor ////////////////////////////////////////////////////////
|
// PlotData constructor ////////////////////////////////////////////////////////
|
||||||
PlotData::PlotData(const DMatSample &x, const DMatSample &y)
|
PlotData::PlotData(const DMatSample &x, const DMatSample &y, const bool abs)
|
||||||
{
|
{
|
||||||
if (x[central].rows() != y[central].rows())
|
if (x[central].rows() != y[central].rows())
|
||||||
{
|
{
|
||||||
@ -128,10 +128,17 @@ PlotData::PlotData(const DMatSample &x, const DMatSample &y)
|
|||||||
d.col(3) = y.variance().cwiseSqrt();
|
d.col(3) = y.variance().cwiseSqrt();
|
||||||
tmpFileName = dumpToTmpFile(d);
|
tmpFileName = dumpToTmpFile(d);
|
||||||
pushTmpFile(tmpFileName);
|
pushTmpFile(tmpFileName);
|
||||||
setCommand("'" + tmpFileName + "' u 1:3:2:4 w xyerr");
|
if (!abs)
|
||||||
|
{
|
||||||
|
setCommand("'" + tmpFileName + "' u 1:3:2:4 w xyerr");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setCommand("'" + tmpFileName + "' u 1:(abs($3)):2:4 w xyerr");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PlotData::PlotData(const DVec &x, const DMatSample &y)
|
PlotData::PlotData(const DVec &x, const DMatSample &y, const bool abs)
|
||||||
{
|
{
|
||||||
if (x.rows() != y[central].rows())
|
if (x.rows() != y[central].rows())
|
||||||
{
|
{
|
||||||
@ -146,10 +153,17 @@ PlotData::PlotData(const DVec &x, const DMatSample &y)
|
|||||||
d.col(2) = y.variance().cwiseSqrt();
|
d.col(2) = y.variance().cwiseSqrt();
|
||||||
tmpFileName = dumpToTmpFile(d);
|
tmpFileName = dumpToTmpFile(d);
|
||||||
pushTmpFile(tmpFileName);
|
pushTmpFile(tmpFileName);
|
||||||
setCommand("'" + tmpFileName + "' u 1:2:3 w yerr");
|
if (!abs)
|
||||||
|
{
|
||||||
|
setCommand("'" + tmpFileName + "' u 1:2:3 w yerr");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setCommand("'" + tmpFileName + "' u 1:(abs($2)):3 w yerr");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PlotData::PlotData(const DMatSample &x, const DVec &y)
|
PlotData::PlotData(const DMatSample &x, const DVec &y, const bool abs)
|
||||||
{
|
{
|
||||||
if (x[central].rows() != y.rows())
|
if (x[central].rows() != y.rows())
|
||||||
{
|
{
|
||||||
@ -164,14 +178,29 @@ PlotData::PlotData(const DMatSample &x, const DVec &y)
|
|||||||
d.col(1) = x.variance().cwiseSqrt();
|
d.col(1) = x.variance().cwiseSqrt();
|
||||||
tmpFileName = dumpToTmpFile(d);
|
tmpFileName = dumpToTmpFile(d);
|
||||||
pushTmpFile(tmpFileName);
|
pushTmpFile(tmpFileName);
|
||||||
setCommand("'" + tmpFileName + "' u 1:3:2 w xerr");
|
if (!abs)
|
||||||
|
{
|
||||||
|
setCommand("'" + tmpFileName + "' u 1:3:2 w xerr");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setCommand("'" + tmpFileName + "' u 1:($3):2 w xerr");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PlotData::PlotData(const XYStatData &data, const Index i, const Index j)
|
PlotData::PlotData(const XYStatData &data, const Index i, const Index j, const bool abs)
|
||||||
{
|
{
|
||||||
string usingCmd, tmpFileName;
|
string usingCmd, tmpFileName;
|
||||||
|
|
||||||
usingCmd = (data.isXExact(i)) ? "u 1:3:4 w yerr" : "u 1:3:2:4 w xyerr";
|
if (!abs)
|
||||||
|
{
|
||||||
|
usingCmd = (data.isXExact(i)) ? "u 1:3:4 w yerr" : "u 1:3:2:4 w xyerr";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usingCmd = (data.isXExact(i)) ? "u 1:(abs($3)):4 w yerr" : "u 1:(abs($3)):2:4 w xyerr";
|
||||||
|
}
|
||||||
|
|
||||||
tmpFileName = dumpToTmpFile(data.getTable(i, j));
|
tmpFileName = dumpToTmpFile(data.getTable(i, j));
|
||||||
pushTmpFile(tmpFileName);
|
pushTmpFile(tmpFileName);
|
||||||
setCommand("'" + tmpFileName + "' " + usingCmd);
|
setCommand("'" + tmpFileName + "' " + usingCmd);
|
||||||
@ -195,6 +224,24 @@ PlotLine::PlotLine(const DVec &x, const DVec &y)
|
|||||||
setCommand("'" + tmpFileName + "' u 1:2 w lines");
|
setCommand("'" + tmpFileName + "' u 1:2 w lines");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PlotPoints constructor ////////////////////////////////////////////////////////
|
||||||
|
PlotPoints::PlotPoints(const DVec &x, const DVec &y)
|
||||||
|
{
|
||||||
|
if (x.size() != y.size())
|
||||||
|
{
|
||||||
|
LATAN_ERROR(Size, "x and y vectors do not have the same size");
|
||||||
|
}
|
||||||
|
|
||||||
|
DMat d(x.size(), 2);
|
||||||
|
string usingCmd, tmpFileName;
|
||||||
|
|
||||||
|
d.col(0) = x;
|
||||||
|
d.col(1) = y;
|
||||||
|
tmpFileName = dumpToTmpFile(d);
|
||||||
|
pushTmpFile(tmpFileName);
|
||||||
|
setCommand("'" + tmpFileName + "' u 1:2");
|
||||||
|
}
|
||||||
|
|
||||||
// PlotHLine constructor ///////////////////////////////////////////////////////
|
// PlotHLine constructor ///////////////////////////////////////////////////////
|
||||||
PlotHLine::PlotHLine(const double y)
|
PlotHLine::PlotHLine(const double y)
|
||||||
{
|
{
|
||||||
@ -217,7 +264,8 @@ PlotBand::PlotBand(const double xMin, const double xMax, const double yMin,
|
|||||||
|
|
||||||
// PlotFunction constructor ////////////////////////////////////////////////////
|
// PlotFunction constructor ////////////////////////////////////////////////////
|
||||||
PlotFunction::PlotFunction(const DoubleFunction &function, const double xMin,
|
PlotFunction::PlotFunction(const DoubleFunction &function, const double xMin,
|
||||||
const double xMax, const unsigned int nPoint)
|
const double xMax, const unsigned int nPoint,
|
||||||
|
const bool abs)
|
||||||
{
|
{
|
||||||
DMat d(nPoint, 2);
|
DMat d(nPoint, 2);
|
||||||
string tmpFileName;
|
string tmpFileName;
|
||||||
@ -230,7 +278,14 @@ PlotFunction::PlotFunction(const DoubleFunction &function, const double xMin,
|
|||||||
}
|
}
|
||||||
tmpFileName = dumpToTmpFile(d);
|
tmpFileName = dumpToTmpFile(d);
|
||||||
pushTmpFile(tmpFileName);
|
pushTmpFile(tmpFileName);
|
||||||
setCommand("'" + tmpFileName + "' u 1:2 w lines");
|
if (!abs)
|
||||||
|
{
|
||||||
|
setCommand("'" + tmpFileName + "' u 1:2 w lines");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setCommand("'" + tmpFileName + "' u 1:(abs($2)) w lines");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PlotPredBand constructor ////////////////////////////////////////////////////
|
// PlotPredBand constructor ////////////////////////////////////////////////////
|
||||||
|
@ -89,10 +89,11 @@ class PlotData: public PlotObject
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// constructor
|
// constructor
|
||||||
PlotData(const DMatSample &x, const DMatSample &y);
|
PlotData(const DMatSample &x, const DMatSample &y, const bool abs = false);
|
||||||
PlotData(const DVec &x, const DMatSample &y);
|
PlotData(const DVec &x, const DMatSample &y, const bool abs = false);
|
||||||
PlotData(const DMatSample &x, const DVec &y);
|
PlotData(const DMatSample &x, const DVec &y, const bool abs = false);
|
||||||
PlotData(const XYStatData &data, const Index i = 0, const Index j = 0);
|
PlotData(const XYStatData &data, const Index i = 0, const Index j = 0,
|
||||||
|
const bool abs = false);
|
||||||
// destructor
|
// destructor
|
||||||
virtual ~PlotData(void) = default;
|
virtual ~PlotData(void) = default;
|
||||||
};
|
};
|
||||||
@ -115,6 +116,15 @@ public:
|
|||||||
virtual ~PlotLine(void) = default;
|
virtual ~PlotLine(void) = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PlotPoints: public PlotObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
PlotPoints(const DVec &x, const DVec &y);
|
||||||
|
// destructor
|
||||||
|
virtual ~PlotPoints(void) = default;
|
||||||
|
};
|
||||||
|
|
||||||
class PlotBand: public PlotObject
|
class PlotBand: public PlotObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -130,7 +140,8 @@ class PlotFunction: public PlotObject
|
|||||||
public:
|
public:
|
||||||
// constructor
|
// constructor
|
||||||
PlotFunction(const DoubleFunction &function, const double xMin,
|
PlotFunction(const DoubleFunction &function, const double xMin,
|
||||||
const double xMax, const unsigned int nPoint = 1000);
|
const double xMax, const unsigned int nPoint = 1000,
|
||||||
|
const bool abs = false);
|
||||||
// destructor
|
// destructor
|
||||||
virtual ~PlotFunction(void) = default;
|
virtual ~PlotFunction(void) = default;
|
||||||
};
|
};
|
||||||
@ -182,6 +193,11 @@ PlotRange(Axis::x, -.5, (m).cols() - .5) <<\
|
|||||||
PlotRange(Axis::y, (m).rows() - .5, -.5) <<\
|
PlotRange(Axis::y, (m).rows() - .5, -.5) <<\
|
||||||
PlotMatrixNoRange(m)
|
PlotMatrixNoRange(m)
|
||||||
|
|
||||||
|
#define PlotCorrMatrix(m)\
|
||||||
|
PlotHeadCommand("set cbrange [-1:1]") <<\
|
||||||
|
PlotHeadCommand("set palette defined (0 'blue', 1 'white', 2 'red')") <<\
|
||||||
|
PlotMatrix(m)
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Plot modifiers *
|
* Plot modifiers *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
117
lib/Core/ThreadPool.cpp
Normal file
117
lib/Core/ThreadPool.cpp
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* ThreadPool.cpp, part of LatAnalyze 3
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 - 2021 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/Core/ThreadPool.hpp>
|
||||||
|
#include <LatAnalyze/includes.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Latan;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* ThreadPool implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructors ////////////////////////////////////////////////////////////////
|
||||||
|
ThreadPool::ThreadPool(void)
|
||||||
|
: ThreadPool(std::thread::hardware_concurrency())
|
||||||
|
{}
|
||||||
|
|
||||||
|
ThreadPool::ThreadPool(const unsigned int nThreads)
|
||||||
|
: nThreads_(nThreads)
|
||||||
|
{
|
||||||
|
for (unsigned int t = 0; t < nThreads_; ++t)
|
||||||
|
{
|
||||||
|
threads_.push_back(thread(&ThreadPool::workerLoop, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor //////////////////////////////////////////////////////////////////
|
||||||
|
ThreadPool::~ThreadPool(void)
|
||||||
|
{
|
||||||
|
terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the number of threads ///////////////////////////////////////////////////
|
||||||
|
unsigned int ThreadPool::getThreadNum(void) const
|
||||||
|
{
|
||||||
|
return nThreads_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the pool mutex for synchronisation //////////////////////////////////////
|
||||||
|
std::mutex & ThreadPool::getMutex(void)
|
||||||
|
{
|
||||||
|
return mutex_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// worker loop /////////////////////////////////////////////////////////////////
|
||||||
|
void ThreadPool::workerLoop(void)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
Job job;
|
||||||
|
{
|
||||||
|
unique_lock<mutex> lock(mutex_);
|
||||||
|
|
||||||
|
condition_.wait(lock, [this](){
|
||||||
|
return !queue_.empty() || terminatePool_;
|
||||||
|
});
|
||||||
|
if (terminatePool_ and queue_.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
job = queue_.front();
|
||||||
|
queue_.pop();
|
||||||
|
}
|
||||||
|
job();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add jobs ////////////////////////////////////////////////////////////////////
|
||||||
|
void ThreadPool::addJob(Job newJob)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
unique_lock<mutex> lock(mutex_);
|
||||||
|
|
||||||
|
queue_.push(newJob);
|
||||||
|
}
|
||||||
|
condition_.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
// critical section ////////////////////////////////////////////////////////////
|
||||||
|
void ThreadPool::critical(Job fn)
|
||||||
|
{
|
||||||
|
unique_lock<mutex> lock(mutex_);
|
||||||
|
|
||||||
|
fn();
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for completion /////////////////////////////////////////////////////////
|
||||||
|
void ThreadPool::terminate(void)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
unique_lock<mutex> lock(mutex_);
|
||||||
|
|
||||||
|
terminatePool_ = true;
|
||||||
|
}
|
||||||
|
condition_.notify_all();
|
||||||
|
for (auto &thread: threads_)
|
||||||
|
{
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
threads_.clear();
|
||||||
|
}
|
56
lib/Core/ThreadPool.hpp
Normal file
56
lib/Core/ThreadPool.hpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* ThreadPool.hpp, part of LatAnalyze 3
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 - 2021 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_ThreadPool_hpp_
|
||||||
|
#define Latan_ThreadPool_hpp_
|
||||||
|
|
||||||
|
#include <LatAnalyze/Global.hpp>
|
||||||
|
|
||||||
|
class ThreadPool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::function<void(void)> Job;
|
||||||
|
public:
|
||||||
|
// constructors/destructor
|
||||||
|
ThreadPool(void);
|
||||||
|
ThreadPool(const unsigned int nThreads);
|
||||||
|
virtual ~ThreadPool(void);
|
||||||
|
// get the number of threads
|
||||||
|
unsigned int getThreadNum(void) const;
|
||||||
|
// get the pool mutex for synchronisation
|
||||||
|
std::mutex & getMutex(void);
|
||||||
|
// add jobs
|
||||||
|
void addJob(Job newJob);
|
||||||
|
// critical section
|
||||||
|
void critical(Job fn);
|
||||||
|
// wait for completion and terminate
|
||||||
|
void terminate(void);
|
||||||
|
private:
|
||||||
|
// worker loop
|
||||||
|
void workerLoop(void);
|
||||||
|
private:
|
||||||
|
unsigned int nThreads_;
|
||||||
|
std::condition_variable condition_;
|
||||||
|
std::vector<std::thread> threads_;
|
||||||
|
bool terminatePool_{false};
|
||||||
|
std::queue<Job> queue_;
|
||||||
|
std::mutex mutex_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -24,6 +24,7 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <complex>
|
#include <complex>
|
||||||
|
#include <condition_variable>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -40,6 +41,7 @@
|
|||||||
#include <stack>
|
#include <stack>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <thread>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
@ -32,6 +32,7 @@ libLatAnalyze_la_SOURCES = \
|
|||||||
Core/MathParser.ypp \
|
Core/MathParser.ypp \
|
||||||
Core/OptParser.cpp \
|
Core/OptParser.cpp \
|
||||||
Core/Plot.cpp \
|
Core/Plot.cpp \
|
||||||
|
Core/ThreadPool.cpp \
|
||||||
Core/Utilities.cpp \
|
Core/Utilities.cpp \
|
||||||
Functional/CompiledFunction.cpp \
|
Functional/CompiledFunction.cpp \
|
||||||
Functional/CompiledModel.cpp \
|
Functional/CompiledModel.cpp \
|
||||||
@ -75,6 +76,7 @@ HPPFILES = \
|
|||||||
Core/OptParser.hpp \
|
Core/OptParser.hpp \
|
||||||
Core/ParserState.hpp \
|
Core/ParserState.hpp \
|
||||||
Core/Plot.hpp \
|
Core/Plot.hpp \
|
||||||
|
Core/ThreadPool.hpp \
|
||||||
Core/stdincludes.hpp \
|
Core/stdincludes.hpp \
|
||||||
Core/Utilities.hpp \
|
Core/Utilities.hpp \
|
||||||
Functional/CompiledFunction.hpp \
|
Functional/CompiledFunction.hpp \
|
||||||
|
@ -19,6 +19,20 @@
|
|||||||
|
|
||||||
#include <LatAnalyze/Numerical/MinuitMinimizer.hpp>
|
#include <LatAnalyze/Numerical/MinuitMinimizer.hpp>
|
||||||
#include <LatAnalyze/includes.hpp>
|
#include <LatAnalyze/includes.hpp>
|
||||||
|
|
||||||
|
// forward declaration necessary in the ROOT-based version of Minuit2
|
||||||
|
namespace ROOT
|
||||||
|
{
|
||||||
|
namespace Fit
|
||||||
|
{
|
||||||
|
class ParameterSettings;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// macros necessary in the ROOT-based version of Minuit2
|
||||||
|
#define ROOT_Math_VecTypes
|
||||||
|
#define MATHCORE_STANDALONE
|
||||||
|
|
||||||
#include <Minuit2/Minuit2Minimizer.h>
|
#include <Minuit2/Minuit2Minimizer.h>
|
||||||
#include <Math/Functor.h>
|
#include <Math/Functor.h>
|
||||||
|
|
||||||
|
@ -103,6 +103,10 @@ 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);
|
||||||
|
// covariance matrix
|
||||||
|
Mat<T> covarianceMatrix(const MatSample<T> &sample) const;
|
||||||
|
Mat<T> varianceMatrix(void) const;
|
||||||
|
Mat<T> correlationMatrix(void) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// non-member operators
|
// non-member operators
|
||||||
@ -379,6 +383,78 @@ void MatSample<T>::resizeMat(const Index nRow, const Index nCol)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// covariance matrix ///////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
Mat<T> MatSample<T>::covarianceMatrix(const MatSample<T> &sample) const
|
||||||
|
{
|
||||||
|
if (((*this)[central].cols() != 1) or (sample[central].cols() != 1))
|
||||||
|
{
|
||||||
|
LATAN_ERROR(Size, "samples have more than one column");
|
||||||
|
}
|
||||||
|
|
||||||
|
Index n1 = (*this)[central].rows(), n2 = sample[central].rows();
|
||||||
|
Index nSample = this->size();
|
||||||
|
Mat<T> tmp1(n1, nSample), tmp2(n2, nSample), res(n1, n2);
|
||||||
|
Mat<T> s1(n1, 1), s2(n2, 1), one(nSample, 1);
|
||||||
|
|
||||||
|
one.fill(1.);
|
||||||
|
s1.fill(0.);
|
||||||
|
s2.fill(0.);
|
||||||
|
for (unsigned int s = 0; s < nSample; ++s)
|
||||||
|
{
|
||||||
|
s1 += (*this)[s];
|
||||||
|
tmp1.col(s) = (*this)[s];
|
||||||
|
}
|
||||||
|
tmp1 -= s1*one.transpose()/static_cast<double>(nSample);
|
||||||
|
for (unsigned int s = 0; s < nSample; ++s)
|
||||||
|
{
|
||||||
|
s2 += sample[s];
|
||||||
|
tmp2.col(s) = sample[s];
|
||||||
|
}
|
||||||
|
tmp2 -= s2*one.transpose()/static_cast<double>(nSample);
|
||||||
|
res = tmp1*tmp2.transpose()/static_cast<double>(nSample - 1);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Mat<T> MatSample<T>::varianceMatrix(void) const
|
||||||
|
{
|
||||||
|
if ((*this)[central].cols() != 1)
|
||||||
|
{
|
||||||
|
LATAN_ERROR(Size, "samples have more than one column");
|
||||||
|
}
|
||||||
|
|
||||||
|
Index n1 = (*this)[central].rows();
|
||||||
|
Index nSample = this->size();
|
||||||
|
Mat<T> tmp1(n1, nSample), res(n1, n1);
|
||||||
|
Mat<T> s1(n1, 1), one(nSample, 1);
|
||||||
|
|
||||||
|
one.fill(1.);
|
||||||
|
s1.fill(0.);
|
||||||
|
for (unsigned int s = 0; s < nSample; ++s)
|
||||||
|
{
|
||||||
|
s1 += (*this)[s];
|
||||||
|
tmp1.col(s) = (*this)[s];
|
||||||
|
}
|
||||||
|
tmp1 -= s1*one.transpose()/static_cast<double>(nSample);
|
||||||
|
res = tmp1*tmp1.transpose()/static_cast<double>(nSample - 1);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Mat<T> MatSample<T>::correlationMatrix(void) const
|
||||||
|
{
|
||||||
|
Mat<T> res = varianceMatrix();
|
||||||
|
Mat<T> invDiag(res.rows(), 1);
|
||||||
|
|
||||||
|
invDiag = res.diagonal();
|
||||||
|
invDiag = invDiag.cwiseInverse().cwiseSqrt();
|
||||||
|
res = (invDiag*invDiag.transpose()).cwiseProduct(res);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
END_LATAN_NAMESPACE
|
END_LATAN_NAMESPACE
|
||||||
|
|
||||||
|
@ -51,14 +51,11 @@ public:
|
|||||||
const T & operator[](const Index s) const;
|
const T & operator[](const Index s) const;
|
||||||
// statistics
|
// statistics
|
||||||
void bin(Index binSize);
|
void bin(Index binSize);
|
||||||
|
T sum(const Index pos = 0, const Index n = -1) const;
|
||||||
|
T meanOld(const Index pos = 0, const Index n = -1) const;
|
||||||
T mean(const Index pos = 0, const Index n = -1) const;
|
T mean(const Index pos = 0, const Index n = -1) const;
|
||||||
T covariance(const StatArray<T, os> &array, const Index pos = 0,
|
T covariance(const StatArray<T, os> &array) const;
|
||||||
const Index n = -1) const;
|
T variance(void) const;
|
||||||
T covarianceMatrix(const StatArray<T, os> &array, 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 correlationMatrix(const Index pos = 0, const Index n = -1) const;
|
|
||||||
// IO type
|
// IO type
|
||||||
virtual IoType getType(void) const;
|
virtual IoType getType(void) const;
|
||||||
public:
|
public:
|
||||||
@ -66,7 +63,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// reduction operations
|
// reduction operations
|
||||||
namespace ReducOp
|
namespace StatOp
|
||||||
{
|
{
|
||||||
// general templates
|
// general templates
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -148,128 +145,67 @@ void StatArray<T, os>::bin(Index binSize)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, Index os>
|
||||||
|
T StatArray<T, os>::sum(const Index pos, const Index n) const
|
||||||
|
{
|
||||||
|
T result;
|
||||||
|
const Index m = (n >= 0) ? n : size();
|
||||||
|
|
||||||
|
result = (*this)[pos];
|
||||||
|
for (Index i = pos + 1; i < pos + m; ++i)
|
||||||
|
{
|
||||||
|
result += (*this)[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, Index os>
|
template <typename T, Index os>
|
||||||
T StatArray<T, os>::mean(const Index pos, const Index n) const
|
T StatArray<T, os>::mean(const Index pos, const Index n) const
|
||||||
{
|
{
|
||||||
T result = T();
|
|
||||||
const Index m = (n >= 0) ? n : size();
|
const Index m = (n >= 0) ? n : size();
|
||||||
|
|
||||||
if (m)
|
return sum(pos, n)/static_cast<double>(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, Index os>
|
||||||
|
T StatArray<T, os>::covariance(const StatArray<T, os> &array) const
|
||||||
|
{
|
||||||
|
T s1, s2, res;
|
||||||
|
|
||||||
|
s1 = array.sum();
|
||||||
|
s2 = this->sum();
|
||||||
|
res = StatOp::prod<T>(array[0], (*this)[0]);
|
||||||
|
for (Index i = 1; i < size(); ++i)
|
||||||
{
|
{
|
||||||
result = this->segment(pos+os, m).redux(&ReducOp::sum<T>);
|
res += StatOp::prod<T>(array[i], (*this)[i]);
|
||||||
}
|
}
|
||||||
return result/static_cast<double>(m);
|
res -= StatOp::prod<T>(s1, s2)/static_cast<double>(size());
|
||||||
}
|
res /= static_cast<double>(size() - 1);
|
||||||
|
|
||||||
template <typename T, Index os>
|
|
||||||
T StatArray<T, os>::covariance(const StatArray<T, os> &array, const Index pos,
|
|
||||||
const Index n) const
|
|
||||||
{
|
|
||||||
T s1, s2, prs, res = T();
|
|
||||||
const Index m = (n >= 0) ? n : size();
|
|
||||||
|
|
||||||
if (m)
|
|
||||||
{
|
|
||||||
auto arraySeg = array.segment(pos+os, m);
|
|
||||||
auto thisSeg = this->segment(pos+os, m);
|
|
||||||
|
|
||||||
s1 = thisSeg.redux(&ReducOp::sum<T>);
|
|
||||||
s2 = arraySeg.redux(&ReducOp::sum<T>);
|
|
||||||
prs = thisSeg.binaryExpr(arraySeg, &ReducOp::prod<T>)
|
|
||||||
.redux(&ReducOp::sum<T>);
|
|
||||||
res = prs - ReducOp::prod(s1, s2)/static_cast<double>(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res/static_cast<double>(m - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, Index os>
|
|
||||||
T StatArray<T, os>::covarianceMatrix(const StatArray<T, os> &array,
|
|
||||||
const Index pos, const Index n) const
|
|
||||||
{
|
|
||||||
T s1, s2, prs, res = T();
|
|
||||||
const Index m = (n >= 0) ? n : size();
|
|
||||||
|
|
||||||
if (m)
|
|
||||||
{
|
|
||||||
auto arraySeg = array.segment(pos+os, m);
|
|
||||||
auto thisSeg = this->segment(pos+os, m);
|
|
||||||
|
|
||||||
s1 = thisSeg.redux(&ReducOp::sum<T>);
|
|
||||||
s2 = arraySeg.redux(&ReducOp::sum<T>);
|
|
||||||
prs = thisSeg.binaryExpr(arraySeg, &ReducOp::tensProd<T>)
|
|
||||||
.redux(&ReducOp::sum<T>);
|
|
||||||
res = prs - ReducOp::tensProd(s1, s2)/static_cast<double>(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res/static_cast<double>(m - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, Index os>
|
|
||||||
T StatArray<T, os>::variance(const Index pos, const Index n) const
|
|
||||||
{
|
|
||||||
return covariance(*this, pos, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, Index os>
|
|
||||||
T StatArray<T, os>::varianceMatrix(const Index pos, const Index n) const
|
|
||||||
{
|
|
||||||
return covarianceMatrix(*this, pos, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, Index os>
|
|
||||||
T StatArray<T, os>::correlationMatrix(const Index pos, const Index n) const
|
|
||||||
{
|
|
||||||
T res = varianceMatrix(pos, n);
|
|
||||||
T invDiag(res.rows(), 1);
|
|
||||||
|
|
||||||
invDiag = res.diagonal();
|
|
||||||
invDiag = invDiag.cwiseInverse().cwiseSqrt();
|
|
||||||
res = (invDiag*invDiag.transpose()).cwiseProduct(res);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reduction operations ////////////////////////////////////////////////////////
|
template <typename T, Index os>
|
||||||
namespace ReducOp
|
T StatArray<T, os>::variance(void) const
|
||||||
{
|
{
|
||||||
template <typename T>
|
return covariance(*this);
|
||||||
inline T sum(const T &a, const T &b)
|
}
|
||||||
{
|
|
||||||
return a + b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// reduction operations ////////////////////////////////////////////////////////
|
||||||
|
namespace StatOp
|
||||||
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T prod(const T &a, const T &b)
|
inline T prod(const T &a, const T &b)
|
||||||
{
|
{
|
||||||
return a*b;
|
return a*b;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T tensProd(const T &v1 __dumb, const T &v2 __dumb)
|
|
||||||
{
|
|
||||||
LATAN_ERROR(Implementation,
|
|
||||||
"tensorial product not implemented for this type");
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline Mat<double> prod(const Mat<double> &a, const Mat<double> &b)
|
inline Mat<double> prod(const Mat<double> &a, const Mat<double> &b)
|
||||||
{
|
{
|
||||||
return a.cwiseProduct(b);
|
return a.cwiseProduct(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
inline Mat<double> tensProd(const Mat<double> &v1,
|
|
||||||
const Mat<double> &v2)
|
|
||||||
{
|
|
||||||
if ((v1.cols() != 1) or (v2.cols() != 1))
|
|
||||||
{
|
|
||||||
LATAN_ERROR(Size,
|
|
||||||
"tensorial product is only valid with column vectors");
|
|
||||||
}
|
|
||||||
|
|
||||||
return v1*v2.transpose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IO type /////////////////////////////////////////////////////////////////////
|
// IO type /////////////////////////////////////////////////////////////////////
|
||||||
|
@ -62,6 +62,11 @@ double SampleFitResult::getPValue(const Index s) const
|
|||||||
return Math::chi2PValue(getChi2(s), getNDof());
|
return Math::chi2PValue(getChi2(s), getNDof());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double SampleFitResult::getCorrRangeDb(void) const
|
||||||
|
{
|
||||||
|
return corrRangeDb_;
|
||||||
|
}
|
||||||
|
|
||||||
double SampleFitResult::getCcdf(const Index s) const
|
double SampleFitResult::getCcdf(const Index s) const
|
||||||
{
|
{
|
||||||
return Math::chi2Ccdf(getChi2(s), getNDof());
|
return Math::chi2Ccdf(getChi2(s), getNDof());
|
||||||
@ -107,9 +112,11 @@ void SampleFitResult::print(const bool printXsi, ostream &out) const
|
|||||||
getChi2(), static_cast<int>(getNDof()), getChi2PerDof(), getCcdf(),
|
getChi2(), static_cast<int>(getNDof()), getChi2PerDof(), getCcdf(),
|
||||||
getPValue());
|
getPValue());
|
||||||
out << buf << endl;
|
out << buf << endl;
|
||||||
|
sprintf(buf, "correlation dynamic range= %.1f dB", getCorrRangeDb());
|
||||||
|
out << buf << endl;
|
||||||
for (Index p = 0; p < pMax; ++p)
|
for (Index p = 0; p < pMax; ++p)
|
||||||
{
|
{
|
||||||
sprintf(buf, "%8s= % e +/- %e", parName_[p].c_str(),
|
sprintf(buf, "%12s= % e +/- %e", parName_[p].c_str(),
|
||||||
(*this)[central](p), err(p));
|
(*this)[central](p), err(p));
|
||||||
out << buf << endl;
|
out << buf << endl;
|
||||||
}
|
}
|
||||||
@ -249,6 +256,20 @@ const DMat & XYSampleData::getFitVarMatPInv(void)
|
|||||||
return data_.getFitVarMatPInv();
|
return data_.getFitVarMatPInv();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DMat & XYSampleData::getFitCorrMat(void)
|
||||||
|
{
|
||||||
|
computeVarMat();
|
||||||
|
|
||||||
|
return data_.getFitCorrMat();
|
||||||
|
}
|
||||||
|
|
||||||
|
const DMat & XYSampleData::getFitCorrMatPInv(void)
|
||||||
|
{
|
||||||
|
computeVarMat();
|
||||||
|
|
||||||
|
return data_.getFitCorrMatPInv();
|
||||||
|
}
|
||||||
|
|
||||||
// set data to a particular sample /////////////////////////////////////////////
|
// set data to a particular sample /////////////////////////////////////////////
|
||||||
void XYSampleData::setDataToSample(const Index s)
|
void XYSampleData::setDataToSample(const Index s)
|
||||||
{
|
{
|
||||||
@ -330,9 +351,10 @@ SampleFitResult XYSampleData::fit(std::vector<Minimizer *> &minimizer,
|
|||||||
{
|
{
|
||||||
computeVarMat();
|
computeVarMat();
|
||||||
|
|
||||||
SampleFitResult result;
|
SampleFitResult result;
|
||||||
FitResult sampleResult;
|
FitResult sampleResult;
|
||||||
DVec initCopy = init;
|
DVec initCopy = init;
|
||||||
|
Minimizer::Verbosity verbCopy = minimizer.back()->getVerbosity();
|
||||||
|
|
||||||
result.resize(nSample_);
|
result.resize(nSample_);
|
||||||
result.chi2_.resize(nSample_);
|
result.chi2_.resize(nSample_);
|
||||||
@ -348,9 +370,11 @@ SampleFitResult XYSampleData::fit(std::vector<Minimizer *> &minimizer,
|
|||||||
result.model_[j][s] = sampleResult.getModel(j);
|
result.model_[j][s] = sampleResult.getModel(j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.nPar_ = sampleResult.getNPar();
|
minimizer.back()->setVerbosity(verbCopy);
|
||||||
result.nDof_ = sampleResult.nDof_;
|
result.nPar_ = sampleResult.getNPar();
|
||||||
result.parName_ = sampleResult.parName_;
|
result.nDof_ = sampleResult.nDof_;
|
||||||
|
result.parName_ = sampleResult.parName_;
|
||||||
|
result.corrRangeDb_ = Math::svdDynamicRangeDb(getFitCorrMat());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -382,6 +406,29 @@ XYSampleData XYSampleData::getResiduals(const SampleFitResult &fit)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XYSampleData XYSampleData::getNormalisedResiduals(const SampleFitResult &fit)
|
||||||
|
{
|
||||||
|
XYSampleData res(*this);
|
||||||
|
|
||||||
|
for (Index j = 0; j < getNYDim(); ++j)
|
||||||
|
{
|
||||||
|
const DoubleFunctionSample &f = fit.getModel(_, j);
|
||||||
|
|
||||||
|
for (auto &p: yData_[j])
|
||||||
|
{
|
||||||
|
res.y(p.first, j) -= f(x(p.first));
|
||||||
|
}
|
||||||
|
|
||||||
|
const DMat &var = res.getYYVar(j, j);
|
||||||
|
for (auto &p: yData_[j])
|
||||||
|
{
|
||||||
|
res.y(p.first, j) /= sqrt(var(p.first, p.first));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
XYSampleData XYSampleData::getPartialResiduals(const SampleFitResult &fit,
|
XYSampleData XYSampleData::getPartialResiduals(const SampleFitResult &fit,
|
||||||
const DVec &ref, const Index i)
|
const DVec &ref, const Index i)
|
||||||
{
|
{
|
||||||
|
@ -49,6 +49,7 @@ public:
|
|||||||
double getNDof(void) const;
|
double getNDof(void) const;
|
||||||
Index getNPar(void) const;
|
Index getNPar(void) const;
|
||||||
double getPValue(const Index s = central) const;
|
double getPValue(const Index s = central) const;
|
||||||
|
double getCorrRangeDb(void) const;
|
||||||
double getCcdf(const Index s = central) const;
|
double getCcdf(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;
|
||||||
@ -60,6 +61,7 @@ public:
|
|||||||
std::ostream &out = std::cout) const;
|
std::ostream &out = std::cout) const;
|
||||||
private:
|
private:
|
||||||
DSample chi2_;
|
DSample chi2_;
|
||||||
|
double corrRangeDb_{0.};
|
||||||
Index nDof_{0}, nPar_{0};
|
Index nDof_{0}, nPar_{0};
|
||||||
std::vector<DoubleFunctionSample> model_;
|
std::vector<DoubleFunctionSample> model_;
|
||||||
std::vector<std::string> parName_;
|
std::vector<std::string> parName_;
|
||||||
@ -91,9 +93,11 @@ public:
|
|||||||
const DMat & getXYVar(const Index i, const Index j);
|
const DMat & getXYVar(const Index i, const Index j);
|
||||||
DVec getXError(const Index i);
|
DVec getXError(const Index i);
|
||||||
DVec getYError(const Index j);
|
DVec getYError(const Index j);
|
||||||
// get total fit variance matrix and its pseudo-inverse
|
// get total fit variance & correlation matrices and their pseudo-inverse
|
||||||
const DMat & getFitVarMat(void);
|
const DMat & getFitVarMat(void);
|
||||||
const DMat & getFitVarMatPInv(void);
|
const DMat & getFitVarMatPInv(void);
|
||||||
|
const DMat & getFitCorrMat(void);
|
||||||
|
const DMat & getFitCorrMatPInv(void);
|
||||||
// set data to a particular sample
|
// set data to a particular sample
|
||||||
void setDataToSample(const Index s);
|
void setDataToSample(const Index s);
|
||||||
// get internal XYStatData
|
// get internal XYStatData
|
||||||
@ -118,6 +122,7 @@ public:
|
|||||||
const DoubleModel &model, const Ts... models);
|
const DoubleModel &model, const Ts... models);
|
||||||
// residuals
|
// residuals
|
||||||
XYSampleData getResiduals(const SampleFitResult &fit);
|
XYSampleData getResiduals(const SampleFitResult &fit);
|
||||||
|
XYSampleData getNormalisedResiduals(const SampleFitResult &fit);
|
||||||
XYSampleData getPartialResiduals(const SampleFitResult &fit, const DVec &x,
|
XYSampleData getPartialResiduals(const SampleFitResult &fit, const DVec &x,
|
||||||
const Index i);
|
const Index i);
|
||||||
private:
|
private:
|
||||||
|
@ -60,6 +60,11 @@ double FitResult::getCcdf(void) const
|
|||||||
return Math::chi2Ccdf(getChi2(), getNDof());;
|
return Math::chi2Ccdf(getChi2(), getNDof());;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double FitResult::getCorrRangeDb(void) const
|
||||||
|
{
|
||||||
|
return corrRangeDb_;
|
||||||
|
}
|
||||||
|
|
||||||
const DoubleFunction & FitResult::getModel(const Index j) const
|
const DoubleFunction & FitResult::getModel(const Index j) const
|
||||||
{
|
{
|
||||||
return model_[j];
|
return model_[j];
|
||||||
@ -75,9 +80,11 @@ void FitResult::print(const bool printXsi, ostream &out) const
|
|||||||
getChi2(), static_cast<int>(getNDof()), getChi2PerDof(), getCcdf(),
|
getChi2(), static_cast<int>(getNDof()), getChi2PerDof(), getCcdf(),
|
||||||
getPValue());
|
getPValue());
|
||||||
out << buf << endl;
|
out << buf << endl;
|
||||||
|
sprintf(buf, "correlation dynamic range= %.1f dB", getCorrRangeDb());
|
||||||
|
out << buf << endl;
|
||||||
for (Index p = 0; p < pMax; ++p)
|
for (Index p = 0; p < pMax; ++p)
|
||||||
{
|
{
|
||||||
sprintf(buf, "%8s= %e", parName_[p].c_str(), (*this)(p));
|
sprintf(buf, "%12s= %e", parName_[p].c_str(), (*this)(p));
|
||||||
out << buf << endl;
|
out << buf << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,7 +223,7 @@ DVec XYStatData::getXError(const Index i) const
|
|||||||
|
|
||||||
DVec XYStatData::getYError(const Index j) const
|
DVec XYStatData::getYError(const Index j) const
|
||||||
{
|
{
|
||||||
checkXDim(j);
|
checkYDim(j);
|
||||||
|
|
||||||
return yyVar_(j, j).diagonal().cwiseSqrt();
|
return yyVar_(j, j).diagonal().cwiseSqrt();
|
||||||
}
|
}
|
||||||
@ -259,6 +266,20 @@ const DMat & XYStatData::getFitVarMatPInv(void)
|
|||||||
return fitVarInv_;
|
return fitVarInv_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DMat & XYStatData::getFitCorrMat(void)
|
||||||
|
{
|
||||||
|
updateFitVarMat();
|
||||||
|
|
||||||
|
return fitCorr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DMat & XYStatData::getFitCorrMatPInv(void)
|
||||||
|
{
|
||||||
|
updateFitVarMat();
|
||||||
|
|
||||||
|
return fitCorrInv_;
|
||||||
|
}
|
||||||
|
|
||||||
// fit /////////////////////////////////////////////////////////////////////////
|
// fit /////////////////////////////////////////////////////////////////////////
|
||||||
FitResult XYStatData::fit(vector<Minimizer *> &minimizer, const DVec &init,
|
FitResult XYStatData::fit(vector<Minimizer *> &minimizer, const DVec &init,
|
||||||
const vector<const DoubleModel *> &v)
|
const vector<const DoubleModel *> &v)
|
||||||
@ -337,9 +358,10 @@ FitResult XYStatData::fit(vector<Minimizer *> &minimizer, const DVec &init,
|
|||||||
result = (*m)(chi2);
|
result = (*m)(chi2);
|
||||||
totalInit = result;
|
totalInit = result;
|
||||||
}
|
}
|
||||||
result.chi2_ = chi2(result);
|
result.corrRangeDb_ = Math::svdDynamicRangeDb(getFitCorrMat());
|
||||||
result.nPar_ = nPar;
|
result.chi2_ = chi2(result);
|
||||||
result.nDof_ = layout.totalYSize - nPar;
|
result.nPar_ = nPar;
|
||||||
|
result.nDof_ = layout.totalYSize - nPar;
|
||||||
result.model_.resize(v.size());
|
result.model_.resize(v.size());
|
||||||
for (unsigned int j = 0; j < v.size(); ++j)
|
for (unsigned int j = 0; j < v.size(); ++j)
|
||||||
{
|
{
|
||||||
@ -379,6 +401,27 @@ XYStatData XYStatData::getResiduals(const FitResult &fit)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XYStatData XYStatData::getNormalisedResiduals(const FitResult &fit)
|
||||||
|
{
|
||||||
|
XYStatData res(*this);
|
||||||
|
|
||||||
|
for (Index j = 0; j < getNYDim(); ++j)
|
||||||
|
{
|
||||||
|
const DoubleFunction &f = fit.getModel(j);
|
||||||
|
const DVec err = getYError(j);
|
||||||
|
Index row = 0;
|
||||||
|
|
||||||
|
for (auto &p: yData_[j])
|
||||||
|
{
|
||||||
|
res.y(p.first, j) -= f(x(p.first));
|
||||||
|
res.y(p.first, j) /= err(row);
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
XYStatData XYStatData::getPartialResiduals(const FitResult &fit,
|
XYStatData XYStatData::getPartialResiduals(const FitResult &fit,
|
||||||
const DVec &ref, const Index i)
|
const DVec &ref, const Index i)
|
||||||
{
|
{
|
||||||
@ -530,8 +573,11 @@ void XYStatData::updateFitVarMat(void)
|
|||||||
chi2DataVec_.resize(layout.totalSize);
|
chi2DataVec_.resize(layout.totalSize);
|
||||||
chi2ModVec_.resize(layout.totalSize);
|
chi2ModVec_.resize(layout.totalSize);
|
||||||
chi2Vec_.resize(layout.totalSize);
|
chi2Vec_.resize(layout.totalSize);
|
||||||
fitVar_ = fitVar_.cwiseProduct(makeCorrFilter());
|
fitVar_ = fitVar_.cwiseProduct(makeCorrFilter());
|
||||||
fitVarInv_ = fitVar_.pInverse(getSvdTolerance());
|
fitCorr_ = Math::varToCorr(fitVar_);
|
||||||
|
fitCorrInv_ = fitCorr_.pInverse(getSvdTolerance());
|
||||||
|
fitVarInv_ = Math::corrToVar(fitCorrInv_, fitVar_.diagonal().cwiseInverse());
|
||||||
|
|
||||||
scheduleFitVarMatInit(false);
|
scheduleFitVarMatInit(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,12 +48,13 @@ public:
|
|||||||
Index getNPar(void) const;
|
Index getNPar(void) const;
|
||||||
double getPValue(void) const;
|
double getPValue(void) const;
|
||||||
double getCcdf(void) const;
|
double getCcdf(void) const;
|
||||||
|
double getCorrRangeDb(void) const;
|
||||||
const DoubleFunction & getModel(const Index j = 0) const;
|
const DoubleFunction & getModel(const Index j = 0) const;
|
||||||
// IO
|
// IO
|
||||||
void print(const bool printXsi = false,
|
void print(const bool printXsi = false,
|
||||||
std::ostream &out = std::cout) const;
|
std::ostream &out = std::cout) const;
|
||||||
private:
|
private:
|
||||||
double chi2_{0.};
|
double chi2_{0.}, corrRangeDb_{0.};
|
||||||
Index nDof_{0}, nPar_{0};
|
Index nDof_{0}, nPar_{0};
|
||||||
std::vector<DoubleFunction> model_;
|
std::vector<DoubleFunction> model_;
|
||||||
std::vector<std::string> parName_;
|
std::vector<std::string> parName_;
|
||||||
@ -88,9 +89,11 @@ public:
|
|||||||
DVec getXError(const Index i) const;
|
DVec getXError(const Index i) const;
|
||||||
DVec getYError(const Index j) const;
|
DVec getYError(const Index j) const;
|
||||||
DMat getTable(const Index i, const Index j) const;
|
DMat getTable(const Index i, const Index j) const;
|
||||||
// get total fit variance matrix and its pseudo-inverse
|
// get total fit variance & correlation matrices and their pseudo-inverse
|
||||||
const DMat & getFitVarMat(void);
|
const DMat & getFitVarMat(void);
|
||||||
const DMat & getFitVarMatPInv(void);
|
const DMat & getFitVarMatPInv(void);
|
||||||
|
const DMat & getFitCorrMat(void);
|
||||||
|
const DMat & getFitCorrMatPInv(void);
|
||||||
// fit
|
// fit
|
||||||
FitResult fit(std::vector<Minimizer *> &minimizer, const DVec &init,
|
FitResult fit(std::vector<Minimizer *> &minimizer, const DVec &init,
|
||||||
const std::vector<const DoubleModel *> &v);
|
const std::vector<const DoubleModel *> &v);
|
||||||
@ -104,6 +107,7 @@ public:
|
|||||||
const DoubleModel &model, const Ts... models);
|
const DoubleModel &model, const Ts... models);
|
||||||
// residuals
|
// residuals
|
||||||
XYStatData getResiduals(const FitResult &fit);
|
XYStatData getResiduals(const FitResult &fit);
|
||||||
|
XYStatData getNormalisedResiduals(const FitResult &fit);
|
||||||
XYStatData getPartialResiduals(const FitResult &fit, const DVec &ref,
|
XYStatData getPartialResiduals(const FitResult &fit, const DVec &ref,
|
||||||
const Index i);
|
const Index i);
|
||||||
protected:
|
protected:
|
||||||
@ -130,7 +134,7 @@ private:
|
|||||||
std::vector<DVec> xData_;
|
std::vector<DVec> xData_;
|
||||||
std::vector<DVec> xMap_;
|
std::vector<DVec> xMap_;
|
||||||
Mat<DMat> xxVar_, yyVar_, xyVar_;
|
Mat<DMat> xxVar_, yyVar_, xyVar_;
|
||||||
DMat fitVar_, fitVarInv_;
|
DMat fitVar_, fitVarInv_, fitCorr_, fitCorrInv_;
|
||||||
DVec chi2DataVec_, chi2ModVec_, chi2Vec_;
|
DVec chi2DataVec_, chi2ModVec_, chi2Vec_;
|
||||||
DVec xBuf_;
|
DVec xBuf_;
|
||||||
bool initXMap_{true};
|
bool initXMap_{true};
|
||||||
|
@ -67,7 +67,8 @@ int main(int argc, char *argv[])
|
|||||||
sample = sample.block(0, 0, sample[central].rows(), 1);
|
sample = sample.block(0, 0, sample[central].rows(), 1);
|
||||||
var = sample.varianceMatrix();
|
var = sample.varianceMatrix();
|
||||||
corr = sample.correlationMatrix();
|
corr = sample.correlationMatrix();
|
||||||
p << PlotMatrix(corr);
|
|
||||||
|
p << PlotCorrMatrix(corr);
|
||||||
p.display();
|
p.display();
|
||||||
if (!outVarName.empty())
|
if (!outVarName.empty())
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user