diff --git a/smatrix/CreateBinaryOp.sh b/smatrix/CreateBinaryOp.sh new file mode 100755 index 0000000000000000000000000000000000000000..2c2edd753411cb8bffb52e9bea42e950069019b9 --- /dev/null +++ b/smatrix/CreateBinaryOp.sh @@ -0,0 +1,208 @@ +#!/bin/bash +# +# Script to generate binary operators for SVector & SMatrix class. +# The operator is applied for each element: +# C(i,j) = A(i,j) OP B(i,j) +# +# author: T. Glebe +# +# MPI fuer Kernphysik +# Saupfercheckweg 1 +# D-69117 Heidelberg +# +# 19. Mar 2001 (TG) created +# +########################################################################## + +OUTPUTFILE="BinaryOperators.hh" + +# Format: Class name, Function name, operator +OPLIST=" +AddOp,operator+,+ +MinOp,operator-,- +MulOp,operator*,* +DivOp,operator/,/ +" + + +# generate code: +( +echo "\ +#ifndef __BINARYOPERATORS_HH +#define __BINARYOPERATORS_HH +//====================================================== +// +// ATTENTION: This file was automatically generated, +// do not edit! +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +//====================================================== + +template <class T, unsigned int D> class SVector; +template <class T, unsigned int D1, unsigned int D2> class SMatrix; +" + + for i in $OPLIST; do + CNAM=`echo $i | cut -d, -f1` + FNAM=`echo $i | cut -d, -f2` + OPER=`echo $i | cut -d, -f3` + + echo " +//============================================================================== +// $CNAM +//============================================================================== +template <class T> +class $CNAM { +public: + static inline T apply(const T& lhs, const T& rhs) { + return lhs ${OPER} rhs; + } +}; +" + +# =========== SVector / Expr =============== +CMBLIST=" + +SVector<T,D>++SVector<T,D> + class_A,+Expr<A,T,D>++SVector<T,D> + +SVector<T,D>+class_A,+Expr<A,T,D> + class_A,+Expr<A,T,D>+class_B,+Expr<B,T,D> +" + for j in $CMBLIST; do + CL1=`echo $j | cut -d+ -f1 | tr '_' ' '` + TY1=`echo $j | cut -d+ -f2 | tr '_' ' '` + CL2=`echo $j | cut -d+ -f3 | tr '_' ' '` + TY2=`echo $j | cut -d+ -f4 | tr '_' ' '` + +echo " +//============================================================================== +// $FNAM (SVector, binary) +//============================================================================== +template <${CL1} ${CL2} class T, unsigned int D> +inline Expr<BinaryOp<${CNAM}<T>, ${TY1}, ${TY2}, T>, T, D> + ${FNAM}(const ${TY1}& lhs, const ${TY2}& rhs) { + typedef BinaryOp<${CNAM}<T>, ${TY1}, ${TY2}, T> ${CNAM}BinOp; + + return Expr<${CNAM}BinOp,T,D>(${CNAM}BinOp(${CNAM}<T>(),lhs,rhs)); +} +" + done + +# =========== SVector Constant =============== +CNSTLIST=" + +SVector<T,D> + class_B,+Expr<B,T,D> +" + + for j in $CNSTLIST; do + CL1=`echo $j | cut -d+ -f1 | tr '_' ' '` + TY1=`echo $j | cut -d+ -f2 | tr '_' ' '` + +echo " +//============================================================================== +// $FNAM (SVector, binary, Constant) +//============================================================================== +template <class A, ${CL1} class T, unsigned int D> +inline Expr<BinaryOp<${CNAM}<T>, ${TY1}, Constant<A>, T>, T, D> + ${FNAM}(const ${TY1}& lhs, const A& rhs) { + typedef BinaryOp<${CNAM}<T>, ${TY1}, Constant<A>, T> ${CNAM}BinOp; + + return Expr<${CNAM}BinOp,T,D>(${CNAM}BinOp(${CNAM}<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// $FNAM (SVector, binary, Constant) +//============================================================================== +template <class A, ${CL1} class T, unsigned int D> +inline Expr<BinaryOp<${CNAM}<T>, Constant<A>, ${TY1}, T>, T, D> + ${FNAM}(const A& lhs, const ${TY1}& rhs) { + typedef BinaryOp<${CNAM}<T>, Constant<A>, ${TY1}, T> ${CNAM}BinOp; + + return Expr<${CNAM}BinOp,T,D>(${CNAM}BinOp(${CNAM}<T>(),Constant<A>(lhs),rhs)); +} +" + done + + +# =========== SMatrix / Expr =============== +CMBLIST=" + +SMatrix<T,D,D2>++SMatrix<T,D,D2> + class_A,+Expr<A,T,D,D2>++SMatrix<T,D,D2> + +SMatrix<T,D,D2>+class_A,+Expr<A,T,D,D2> + class_A,+Expr<A,T,D,D2>+class_B,+Expr<B,T,D,D2> +" + +# component wise multiplication should not occupy operator*() + if [ "$OPER" == "*" ]; then + MFNAM="times" + else + MFNAM=$FNAM + fi + + for j in $CMBLIST; do + CL1=`echo $j | cut -d+ -f1 | tr '_' ' '` + TY1=`echo $j | cut -d+ -f2 | tr '_' ' '` + CL2=`echo $j | cut -d+ -f3 | tr '_' ' '` + TY2=`echo $j | cut -d+ -f4 | tr '_' ' '` + +echo " +//============================================================================== +// $MFNAM (SMatrix, binary) +//============================================================================== +template <${CL1} ${CL2} class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<${CNAM}<T>, ${TY1}, ${TY2}, T>, T, D, D2> + ${MFNAM}(const ${TY1}& lhs, const ${TY2}& rhs) { + typedef BinaryOp<${CNAM}<T>, ${TY1}, ${TY2}, T> ${CNAM}BinOp; + + return Expr<${CNAM}BinOp,T,D,D2>(${CNAM}BinOp(${CNAM}<T>(),lhs,rhs)); +} +" + done + + +# =========== SMatrix Constant =============== +CNSTLIST=" + +SMatrix<T,D,D2> + class_B,+Expr<B,T,D,D2> +" + + for j in $CNSTLIST; do + CL1=`echo $j | cut -d+ -f1 | tr '_' ' '` + TY1=`echo $j | cut -d+ -f2 | tr '_' ' '` + +echo " +//============================================================================== +// $FNAM (SMatrix, binary, Constant) +//============================================================================== +template <class A, ${CL1} class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<${CNAM}<T>, ${TY1}, Constant<A>, T>, T, D, D2> + ${FNAM}(const ${TY1}& lhs, const A& rhs) { + typedef BinaryOp<${CNAM}<T>, ${TY1}, Constant<A>, T> ${CNAM}BinOp; + + return Expr<${CNAM}BinOp,T,D,D2>(${CNAM}BinOp(${CNAM}<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// $FNAM (SMatrix, binary, Constant) +//============================================================================== +template <class A, ${CL1} class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<${CNAM}<T>, Constant<A>, ${TY1}, T>, T, D, D2> + ${FNAM}(const A& lhs, const ${TY1}& rhs) { + typedef BinaryOp<${CNAM}<T>, Constant<A>, ${TY1}, T> ${CNAM}BinOp; + + return Expr<${CNAM}BinOp,T,D,D2>(${CNAM}BinOp(${CNAM}<T>(),Constant<A>(lhs),rhs)); +} +" + done +done + +echo "#endif" +) > $OUTPUTFILE + +echo "$OUTPUTFILE generated" \ No newline at end of file diff --git a/smatrix/CreateUnaryOp.sh b/smatrix/CreateUnaryOp.sh new file mode 100755 index 0000000000000000000000000000000000000000..4c2866f1093cdd17bbf73f3e8bb69af24e28c04e --- /dev/null +++ b/smatrix/CreateUnaryOp.sh @@ -0,0 +1,120 @@ +#!/bin/bash +# +# Script to generate unary operators for SVector and SMatrix class. +# The operator is applied for each element: +# C(i,j) = OP( B(i,j) ) +# +# author: T. Glebe +# +# MPI fuer Kernphysik +# Saupfercheckweg 1 +# D-69117 Heidelberg +# +# 19. Mar 2001 (TG) created +# 04. Apr 2001 (TG) Sqrt added +# +########################################################################## + +OUTPUTFILE="UnaryOperators.hh" + +# Format: Class name, Function name, operator +OPLIST=" +Minus,operator-,- +Fabs,fabs,fabs +Sqr,sqr,square +Sqrt,sqrt,sqrt +" + +# generate code: +( +echo "\ +#ifndef __UNARYOPERATORS_HH +#define __UNARYOPERATORS_HH +//====================================================== +// +// ATTENTION: This file was automatically generated, +// do not edit! +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +//====================================================== + +template <class T, unsigned int D> class SVector; +template <class T, unsigned int D1, unsigned int D2> class SMatrix; +" + + for i in $OPLIST; do + CNAM=`echo $i | cut -d, -f1` + FNAM=`echo $i | cut -d, -f2` + OPER=`echo $i | cut -d, -f3` + + echo " +//============================================================================== +// $CNAM +//============================================================================== +template <class T> +class $CNAM { +public: + static inline T apply(const T& rhs) { + return ${OPER}(rhs); + } +}; + +//============================================================================== +// $FNAM (Expr, unary) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<UnaryOp<${CNAM}<T>, Expr<A,T,D>, T>, T, D> + ${FNAM}(const Expr<A,T,D>& rhs) { + typedef UnaryOp<${CNAM}<T>, Expr<A,T,D>, T> ${CNAM}UnaryOp; + + return Expr<${CNAM}UnaryOp,T,D>(${CNAM}UnaryOp(${CNAM}<T>(),rhs)); +} + + +//============================================================================== +// $FNAM (SVector, unary) +//============================================================================== +template <class T, unsigned int D> +inline Expr<UnaryOp<${CNAM}<T>, SVector<T,D>, T>, T, D> + ${FNAM}(const SVector<T,D>& rhs) { + typedef UnaryOp<${CNAM}<T>, SVector<T,D>, T> ${CNAM}UnaryOp; + + return Expr<${CNAM}UnaryOp,T,D>(${CNAM}UnaryOp(${CNAM}<T>(),rhs)); +} + +//============================================================================== +// $FNAM (MatrixExpr, unary) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<UnaryOp<${CNAM}<T>, Expr<A,T,D,D2>, T>, T, D, D2> + ${FNAM}(const Expr<A,T,D,D2>& rhs) { + typedef UnaryOp<${CNAM}<T>, Expr<A,T,D,D2>, T> ${CNAM}UnaryOp; + + return Expr<${CNAM}UnaryOp,T,D,D2>(${CNAM}UnaryOp(${CNAM}<T>(),rhs)); +} + + +//============================================================================== +// $FNAM (SMatrix, unary) +//============================================================================== +template <class T, unsigned int D, unsigned int D2> +inline Expr<UnaryOp<${CNAM}<T>, SMatrix<T,D,D2>, T>, T, D, D2> + ${FNAM}(const SMatrix<T,D,D2>& rhs) { + typedef UnaryOp<${CNAM}<T>, SMatrix<T,D,D2>, T> ${CNAM}UnaryOp; + + return Expr<${CNAM}UnaryOp,T,D,D2>(${CNAM}UnaryOp(${CNAM}<T>(),rhs)); +} +" + done + +echo "#endif" +) > $OUTPUTFILE + +echo "$OUTPUTFILE generated" diff --git a/smatrix/Module.mk b/smatrix/Module.mk new file mode 100644 index 0000000000000000000000000000000000000000..279699d339f1418dbf7664030183e259bc57bdef --- /dev/null +++ b/smatrix/Module.mk @@ -0,0 +1,86 @@ +# Module.mk for mathcore module +# Copyright (c) 2000 Rene Brun and Fons Rademakers +# +# Author: Fons Rademakers, 20/6/2005 + +MODDIR := smatrix +MODDIRS := $(MODDIR)/src +MODDIRI := $(MODDIR)/inc + +SMATRIXDIR := $(MODDIR) +SMATRIXDIRS := $(SMATRIXDIR)/src +SMATRIXDIRI := $(SMATRIXDIR)/inc/Math + +##### libSmatrix ##### +SMATRIXL := $(MODDIRI)/LinkDef.h +#SMATRIXLINC := +SMATRIXDS := $(MODDIRS)/G__Smatrix.cxx +SMATRIXDO := $(SMATRIXDS:.cxx=.o) +SMATRIXDH := $(SMATRIXDS:.cxx=.h) + +SMATRIXDH1 := $(MODDIRI)/Math/SMatrix.h $(MODDIRI)/Math/SVector.h + + + +SMATRIXH1 := $(filter-out $(MODDIRI)/Math/LinkDef%, $(wildcard $(MODDIRI)/Math/*.h)) +SMATRIXH2 := $(filter-out $(MODDIRI)/Math/LinkDef%, $(wildcard $(MODDIRI)/Math/*.icc)) +SMATRIXH := $(SMATRIXH1) $(SMATRIXH2) +SMATRIXS := $(filter-out $(MODDIRS)/G__%,$(wildcard $(MODDIRS)/*.cxx)) +SMATRIXO := $(SMATRIXS:.cxx=.o) + +SMATRIXDEP := $(SMATRIXO:.o=.d) $(SMATRIXDO:.o=.d) + +SMATRIXLIB := $(LPATH)/libSmatrix.$(SOEXT) + +# used in the main Makefile +ALLHDRS += $(patsubst $(MODDIRI)/Math/%.h,include/Math/%.h,$(SMATRIXH1)) +ALLHDRS += $(patsubst $(MODDIRI)/Math/%.icc,include/Math/%.icc,$(SMATRIXH2)) +ALLLIBS += $(SMATRIXLIB) + +# include all dependency files +INCLUDEFILES += $(SMATRIXDEP) + +##### local rules ##### +include/Math/%.h: $(SMATRIXDIRI)/%.h + cp $< $@ + +include/Math/%.icc: $(SMATRIXDIRI)/%.icc + cp $< $@ + +$(SMATRIXLIB): $(SMATRIXO) $(SMATRIXDO) $(MAINLIBS) + @$(MAKELIB) $(PLATFORM) $(LD) "$(LDFLAGS)" \ + "$(SOFLAGS)" libSmatrix.$(SOEXT) $@ \ + "$(SMATRIXO) $(SMATRIXDO)" \ + "$(SMATRIXLIBEXTRA)" + + +$(SMATRIXDS): $(SMATRIXDH1) $(SMATRIXL) $(SMATRIXLINC) $(ROOTCINTTMP) + @echo "Generating dictionary $@..." + @echo "for files $(SMATRIXDH1)" + $(ROOTCINTTMP) -f $@ -c $(SMATRIXDH1) $(SMATRIXL) +# python reflex/python/genreflex/genreflex.py $(SMATRIXDIRS)/Dict.h -I$(SMATRIXDIRI) --selection_file=$(SMATRIXDIRS)/Selection.xml -o $(SMATRIXDIRS)/G__Smatrix.cxx + + +$(SMATRIXDO): $(SMATRIXDS) + $(CXX) $(NOOPT) $(CXXFLAGS) -I. -I$(SMATRIXDIRI) -o $@ -c $< + +all-smatrix: $(SMATRIXLIB) + +map-smatrix: $(RLIBMAP) + $(RLIBMAP) -r $(ROOTMAP) -l $(SMATRIXLIB) \ + -d $(SMATRIXLIBDEP) -c $(SMATRIXL) $(SMATRIXLINC) + +map:: map-smatrix + +clean-smatrix: + @rm -f $(SMATRIXO) $(SMATRIXDO) + +clean:: clean-smatrix + +distclean-smatrix: clean-smatrix + @rm -f $(SMATRIXDEP) $(SMATRIXDS) $(SMATRIXDH) $(SMATRIXLIB) + @rm -rf include/Math + +distclean:: distclean-smatrix + + diff --git a/smatrix/inc/LinkDef.h b/smatrix/inc/LinkDef.h new file mode 100644 index 0000000000000000000000000000000000000000..5e50a4863f27de4a8785f5ef19876f00b86f3488 --- /dev/null +++ b/smatrix/inc/LinkDef.h @@ -0,0 +1,31 @@ +// @(#)root/smatrix:$Name: $:$Id: LinkDef.h,v 1.1 2005/10/28 15:58:38 moneta Exp $ +// Authors: L. Moneta 2005 + + + + +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +//#pragma link C++ namespace tvmet; + +//#pragma link C++ typedef value_type; + +#pragma link C++ namespace ROOT::Math; + +//generate up to 5x5 +#pragma link C++ class ROOT::Math::SMatrix<double,2,2>+; +#pragma link C++ class ROOT::Math::SMatrix<double,3,3>+; +#pragma link C++ class ROOT::Math::SMatrix<double,4,4>+; +#pragma link C++ class ROOT::Math::SMatrix<double,5,5>+; + +#pragma link C++ class ROOT::Math::SVector<double,2>+; +#pragma link C++ class ROOT::Math::SVector<double,3>+; +#pragma link C++ class ROOT::Math::SVector<double,4>+; +#pragma link C++ class ROOT::Math::SVector<double,5>+; + + +#endif diff --git a/smatrix/inc/Math/BinaryOperators.h b/smatrix/inc/Math/BinaryOperators.h new file mode 100644 index 0000000000000000000000000000000000000000..b9051e85906cfe836b97870464a9de9a662fadbf --- /dev/null +++ b/smatrix/inc/Math/BinaryOperators.h @@ -0,0 +1,838 @@ +// @(#)root/smatrix:$Name: $:$Id: BinaryOperators.hv 1.0 2005/11/24 12:00:00 moneta Exp $ +// Authors: T. Glebe, L. Moneta 2005 + +#ifndef ROOT_Math_BinaryOperators +#define ROOT_Math_BinaryOperators +//====================================================== +// +// ATTENTION: This file was automatically generated, +// do not edit! +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +//====================================================== + + +namespace ROOT { + + namespace Math { + + + +template <class T, unsigned int D> class SVector; +template <class T, unsigned int D1, unsigned int D2> class SMatrix; + + +//============================================================================== +// AddOp +//============================================================================== +template <class T> +class AddOp { +public: + static inline T apply(const T& lhs, const T& rhs) { + return lhs + rhs; + } +}; + + +//============================================================================== +// operator+ (SVector, binary) +//============================================================================== +template < class T, unsigned int D> +inline Expr<BinaryOp<AddOp<T>, SVector<T,D>, SVector<T,D>, T>, T, D> + operator+(const SVector<T,D>& lhs, const SVector<T,D>& rhs) { + typedef BinaryOp<AddOp<T>, SVector<T,D>, SVector<T,D>, T> AddOpBinOp; + + return Expr<AddOpBinOp,T,D>(AddOpBinOp(AddOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator+ (SVector, binary) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<BinaryOp<AddOp<T>, Expr<A,T,D>, SVector<T,D>, T>, T, D> + operator+(const Expr<A,T,D>& lhs, const SVector<T,D>& rhs) { + typedef BinaryOp<AddOp<T>, Expr<A,T,D>, SVector<T,D>, T> AddOpBinOp; + + return Expr<AddOpBinOp,T,D>(AddOpBinOp(AddOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator+ (SVector, binary) +//============================================================================== +template < class A, class T, unsigned int D> +inline Expr<BinaryOp<AddOp<T>, SVector<T,D>, Expr<A,T,D>, T>, T, D> + operator+(const SVector<T,D>& lhs, const Expr<A,T,D>& rhs) { + typedef BinaryOp<AddOp<T>, SVector<T,D>, Expr<A,T,D>, T> AddOpBinOp; + + return Expr<AddOpBinOp,T,D>(AddOpBinOp(AddOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator+ (SVector, binary) +//============================================================================== +template <class A, class B, class T, unsigned int D> +inline Expr<BinaryOp<AddOp<T>, Expr<A,T,D>, Expr<B,T,D>, T>, T, D> + operator+(const Expr<A,T,D>& lhs, const Expr<B,T,D>& rhs) { + typedef BinaryOp<AddOp<T>, Expr<A,T,D>, Expr<B,T,D>, T> AddOpBinOp; + + return Expr<AddOpBinOp,T,D>(AddOpBinOp(AddOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator+ (SVector, binary, Constant) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<BinaryOp<AddOp<T>, SVector<T,D>, Constant<A>, T>, T, D> + operator+(const SVector<T,D>& lhs, const A& rhs) { + typedef BinaryOp<AddOp<T>, SVector<T,D>, Constant<A>, T> AddOpBinOp; + + return Expr<AddOpBinOp,T,D>(AddOpBinOp(AddOp<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// operator+ (SVector, binary, Constant) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<BinaryOp<AddOp<T>, Constant<A>, SVector<T,D>, T>, T, D> + operator+(const A& lhs, const SVector<T,D>& rhs) { + typedef BinaryOp<AddOp<T>, Constant<A>, SVector<T,D>, T> AddOpBinOp; + + return Expr<AddOpBinOp,T,D>(AddOpBinOp(AddOp<T>(),Constant<A>(lhs),rhs)); +} + + +//============================================================================== +// operator+ (SVector, binary, Constant) +//============================================================================== +template <class A, class B, class T, unsigned int D> +inline Expr<BinaryOp<AddOp<T>, Expr<B,T,D>, Constant<A>, T>, T, D> + operator+(const Expr<B,T,D>& lhs, const A& rhs) { + typedef BinaryOp<AddOp<T>, Expr<B,T,D>, Constant<A>, T> AddOpBinOp; + + return Expr<AddOpBinOp,T,D>(AddOpBinOp(AddOp<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// operator+ (SVector, binary, Constant) +//============================================================================== +template <class A, class B, class T, unsigned int D> +inline Expr<BinaryOp<AddOp<T>, Constant<A>, Expr<B,T,D>, T>, T, D> + operator+(const A& lhs, const Expr<B,T,D>& rhs) { + typedef BinaryOp<AddOp<T>, Constant<A>, Expr<B,T,D>, T> AddOpBinOp; + + return Expr<AddOpBinOp,T,D>(AddOpBinOp(AddOp<T>(),Constant<A>(lhs),rhs)); +} + + +//============================================================================== +// operator+ (SMatrix, binary) +//============================================================================== +template < class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<AddOp<T>, SMatrix<T,D,D2>, SMatrix<T,D,D2>, T>, T, D, D2> + operator+(const SMatrix<T,D,D2>& lhs, const SMatrix<T,D,D2>& rhs) { + typedef BinaryOp<AddOp<T>, SMatrix<T,D,D2>, SMatrix<T,D,D2>, T> AddOpBinOp; + + return Expr<AddOpBinOp,T,D,D2>(AddOpBinOp(AddOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator+ (SMatrix, binary) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<AddOp<T>, Expr<A,T,D,D2>, SMatrix<T,D,D2>, T>, T, D, D2> + operator+(const Expr<A,T,D,D2>& lhs, const SMatrix<T,D,D2>& rhs) { + typedef BinaryOp<AddOp<T>, Expr<A,T,D,D2>, SMatrix<T,D,D2>, T> AddOpBinOp; + + return Expr<AddOpBinOp,T,D,D2>(AddOpBinOp(AddOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator+ (SMatrix, binary) +//============================================================================== +template < class A, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<AddOp<T>, SMatrix<T,D,D2>, Expr<A,T,D,D2>, T>, T, D, D2> + operator+(const SMatrix<T,D,D2>& lhs, const Expr<A,T,D,D2>& rhs) { + typedef BinaryOp<AddOp<T>, SMatrix<T,D,D2>, Expr<A,T,D,D2>, T> AddOpBinOp; + + return Expr<AddOpBinOp,T,D,D2>(AddOpBinOp(AddOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator+ (SMatrix, binary) +//============================================================================== +template <class A, class B, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<AddOp<T>, Expr<A,T,D,D2>, Expr<B,T,D,D2>, T>, T, D, D2> + operator+(const Expr<A,T,D,D2>& lhs, const Expr<B,T,D,D2>& rhs) { + typedef BinaryOp<AddOp<T>, Expr<A,T,D,D2>, Expr<B,T,D,D2>, T> AddOpBinOp; + + return Expr<AddOpBinOp,T,D,D2>(AddOpBinOp(AddOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator+ (SMatrix, binary, Constant) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<AddOp<T>, SMatrix<T,D,D2>, Constant<A>, T>, T, D, D2> + operator+(const SMatrix<T,D,D2>& lhs, const A& rhs) { + typedef BinaryOp<AddOp<T>, SMatrix<T,D,D2>, Constant<A>, T> AddOpBinOp; + + return Expr<AddOpBinOp,T,D,D2>(AddOpBinOp(AddOp<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// operator+ (SMatrix, binary, Constant) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<AddOp<T>, Constant<A>, SMatrix<T,D,D2>, T>, T, D, D2> + operator+(const A& lhs, const SMatrix<T,D,D2>& rhs) { + typedef BinaryOp<AddOp<T>, Constant<A>, SMatrix<T,D,D2>, T> AddOpBinOp; + + return Expr<AddOpBinOp,T,D,D2>(AddOpBinOp(AddOp<T>(),Constant<A>(lhs),rhs)); +} + + +//============================================================================== +// operator+ (SMatrix, binary, Constant) +//============================================================================== +template <class A, class B, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<AddOp<T>, Expr<B,T,D,D2>, Constant<A>, T>, T, D, D2> + operator+(const Expr<B,T,D,D2>& lhs, const A& rhs) { + typedef BinaryOp<AddOp<T>, Expr<B,T,D,D2>, Constant<A>, T> AddOpBinOp; + + return Expr<AddOpBinOp,T,D,D2>(AddOpBinOp(AddOp<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// operator+ (SMatrix, binary, Constant) +//============================================================================== +template <class A, class B, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<AddOp<T>, Constant<A>, Expr<B,T,D,D2>, T>, T, D, D2> + operator+(const A& lhs, const Expr<B,T,D,D2>& rhs) { + typedef BinaryOp<AddOp<T>, Constant<A>, Expr<B,T,D,D2>, T> AddOpBinOp; + + return Expr<AddOpBinOp,T,D,D2>(AddOpBinOp(AddOp<T>(),Constant<A>(lhs),rhs)); +} + + +//============================================================================== +// MinOp +//============================================================================== +template <class T> +class MinOp { +public: + static inline T apply(const T& lhs, const T& rhs) { + return lhs - rhs; + } +}; + + +//============================================================================== +// operator- (SVector, binary) +//============================================================================== +template < class T, unsigned int D> +inline Expr<BinaryOp<MinOp<T>, SVector<T,D>, SVector<T,D>, T>, T, D> + operator-(const SVector<T,D>& lhs, const SVector<T,D>& rhs) { + typedef BinaryOp<MinOp<T>, SVector<T,D>, SVector<T,D>, T> MinOpBinOp; + + return Expr<MinOpBinOp,T,D>(MinOpBinOp(MinOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator- (SVector, binary) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<BinaryOp<MinOp<T>, Expr<A,T,D>, SVector<T,D>, T>, T, D> + operator-(const Expr<A,T,D>& lhs, const SVector<T,D>& rhs) { + typedef BinaryOp<MinOp<T>, Expr<A,T,D>, SVector<T,D>, T> MinOpBinOp; + + return Expr<MinOpBinOp,T,D>(MinOpBinOp(MinOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator- (SVector, binary) +//============================================================================== +template < class A, class T, unsigned int D> +inline Expr<BinaryOp<MinOp<T>, SVector<T,D>, Expr<A,T,D>, T>, T, D> + operator-(const SVector<T,D>& lhs, const Expr<A,T,D>& rhs) { + typedef BinaryOp<MinOp<T>, SVector<T,D>, Expr<A,T,D>, T> MinOpBinOp; + + return Expr<MinOpBinOp,T,D>(MinOpBinOp(MinOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator- (SVector, binary) +//============================================================================== +template <class A, class B, class T, unsigned int D> +inline Expr<BinaryOp<MinOp<T>, Expr<A,T,D>, Expr<B,T,D>, T>, T, D> + operator-(const Expr<A,T,D>& lhs, const Expr<B,T,D>& rhs) { + typedef BinaryOp<MinOp<T>, Expr<A,T,D>, Expr<B,T,D>, T> MinOpBinOp; + + return Expr<MinOpBinOp,T,D>(MinOpBinOp(MinOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator- (SVector, binary, Constant) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<BinaryOp<MinOp<T>, SVector<T,D>, Constant<A>, T>, T, D> + operator-(const SVector<T,D>& lhs, const A& rhs) { + typedef BinaryOp<MinOp<T>, SVector<T,D>, Constant<A>, T> MinOpBinOp; + + return Expr<MinOpBinOp,T,D>(MinOpBinOp(MinOp<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// operator- (SVector, binary, Constant) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<BinaryOp<MinOp<T>, Constant<A>, SVector<T,D>, T>, T, D> + operator-(const A& lhs, const SVector<T,D>& rhs) { + typedef BinaryOp<MinOp<T>, Constant<A>, SVector<T,D>, T> MinOpBinOp; + + return Expr<MinOpBinOp,T,D>(MinOpBinOp(MinOp<T>(),Constant<A>(lhs),rhs)); +} + + +//============================================================================== +// operator- (SVector, binary, Constant) +//============================================================================== +template <class A, class B, class T, unsigned int D> +inline Expr<BinaryOp<MinOp<T>, Expr<B,T,D>, Constant<A>, T>, T, D> + operator-(const Expr<B,T,D>& lhs, const A& rhs) { + typedef BinaryOp<MinOp<T>, Expr<B,T,D>, Constant<A>, T> MinOpBinOp; + + return Expr<MinOpBinOp,T,D>(MinOpBinOp(MinOp<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// operator- (SVector, binary, Constant) +//============================================================================== +template <class A, class B, class T, unsigned int D> +inline Expr<BinaryOp<MinOp<T>, Constant<A>, Expr<B,T,D>, T>, T, D> + operator-(const A& lhs, const Expr<B,T,D>& rhs) { + typedef BinaryOp<MinOp<T>, Constant<A>, Expr<B,T,D>, T> MinOpBinOp; + + return Expr<MinOpBinOp,T,D>(MinOpBinOp(MinOp<T>(),Constant<A>(lhs),rhs)); +} + + +//============================================================================== +// operator- (SMatrix, binary) +//============================================================================== +template < class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<MinOp<T>, SMatrix<T,D,D2>, SMatrix<T,D,D2>, T>, T, D, D2> + operator-(const SMatrix<T,D,D2>& lhs, const SMatrix<T,D,D2>& rhs) { + typedef BinaryOp<MinOp<T>, SMatrix<T,D,D2>, SMatrix<T,D,D2>, T> MinOpBinOp; + + return Expr<MinOpBinOp,T,D,D2>(MinOpBinOp(MinOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator- (SMatrix, binary) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<MinOp<T>, Expr<A,T,D,D2>, SMatrix<T,D,D2>, T>, T, D, D2> + operator-(const Expr<A,T,D,D2>& lhs, const SMatrix<T,D,D2>& rhs) { + typedef BinaryOp<MinOp<T>, Expr<A,T,D,D2>, SMatrix<T,D,D2>, T> MinOpBinOp; + + return Expr<MinOpBinOp,T,D,D2>(MinOpBinOp(MinOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator- (SMatrix, binary) +//============================================================================== +template < class A, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<MinOp<T>, SMatrix<T,D,D2>, Expr<A,T,D,D2>, T>, T, D, D2> + operator-(const SMatrix<T,D,D2>& lhs, const Expr<A,T,D,D2>& rhs) { + typedef BinaryOp<MinOp<T>, SMatrix<T,D,D2>, Expr<A,T,D,D2>, T> MinOpBinOp; + + return Expr<MinOpBinOp,T,D,D2>(MinOpBinOp(MinOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator- (SMatrix, binary) +//============================================================================== +template <class A, class B, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<MinOp<T>, Expr<A,T,D,D2>, Expr<B,T,D,D2>, T>, T, D, D2> + operator-(const Expr<A,T,D,D2>& lhs, const Expr<B,T,D,D2>& rhs) { + typedef BinaryOp<MinOp<T>, Expr<A,T,D,D2>, Expr<B,T,D,D2>, T> MinOpBinOp; + + return Expr<MinOpBinOp,T,D,D2>(MinOpBinOp(MinOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator- (SMatrix, binary, Constant) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<MinOp<T>, SMatrix<T,D,D2>, Constant<A>, T>, T, D, D2> + operator-(const SMatrix<T,D,D2>& lhs, const A& rhs) { + typedef BinaryOp<MinOp<T>, SMatrix<T,D,D2>, Constant<A>, T> MinOpBinOp; + + return Expr<MinOpBinOp,T,D,D2>(MinOpBinOp(MinOp<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// operator- (SMatrix, binary, Constant) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<MinOp<T>, Constant<A>, SMatrix<T,D,D2>, T>, T, D, D2> + operator-(const A& lhs, const SMatrix<T,D,D2>& rhs) { + typedef BinaryOp<MinOp<T>, Constant<A>, SMatrix<T,D,D2>, T> MinOpBinOp; + + return Expr<MinOpBinOp,T,D,D2>(MinOpBinOp(MinOp<T>(),Constant<A>(lhs),rhs)); +} + + +//============================================================================== +// operator- (SMatrix, binary, Constant) +//============================================================================== +template <class A, class B, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<MinOp<T>, Expr<B,T,D,D2>, Constant<A>, T>, T, D, D2> + operator-(const Expr<B,T,D,D2>& lhs, const A& rhs) { + typedef BinaryOp<MinOp<T>, Expr<B,T,D,D2>, Constant<A>, T> MinOpBinOp; + + return Expr<MinOpBinOp,T,D,D2>(MinOpBinOp(MinOp<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// operator- (SMatrix, binary, Constant) +//============================================================================== +template <class A, class B, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<MinOp<T>, Constant<A>, Expr<B,T,D,D2>, T>, T, D, D2> + operator-(const A& lhs, const Expr<B,T,D,D2>& rhs) { + typedef BinaryOp<MinOp<T>, Constant<A>, Expr<B,T,D,D2>, T> MinOpBinOp; + + return Expr<MinOpBinOp,T,D,D2>(MinOpBinOp(MinOp<T>(),Constant<A>(lhs),rhs)); +} + + +//============================================================================== +// MulOp +//============================================================================== +template <class T> +class MulOp { +public: + static inline T apply(const T& lhs, const T& rhs) { + return lhs * rhs; + } +}; + + +//============================================================================== +// operator* (SVector, binary) +//============================================================================== +template < class T, unsigned int D> +inline Expr<BinaryOp<MulOp<T>, SVector<T,D>, SVector<T,D>, T>, T, D> + operator*(const SVector<T,D>& lhs, const SVector<T,D>& rhs) { + typedef BinaryOp<MulOp<T>, SVector<T,D>, SVector<T,D>, T> MulOpBinOp; + + return Expr<MulOpBinOp,T,D>(MulOpBinOp(MulOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator* (SVector, binary) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<BinaryOp<MulOp<T>, Expr<A,T,D>, SVector<T,D>, T>, T, D> + operator*(const Expr<A,T,D>& lhs, const SVector<T,D>& rhs) { + typedef BinaryOp<MulOp<T>, Expr<A,T,D>, SVector<T,D>, T> MulOpBinOp; + + return Expr<MulOpBinOp,T,D>(MulOpBinOp(MulOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator* (SVector, binary) +//============================================================================== +template < class A, class T, unsigned int D> +inline Expr<BinaryOp<MulOp<T>, SVector<T,D>, Expr<A,T,D>, T>, T, D> + operator*(const SVector<T,D>& lhs, const Expr<A,T,D>& rhs) { + typedef BinaryOp<MulOp<T>, SVector<T,D>, Expr<A,T,D>, T> MulOpBinOp; + + return Expr<MulOpBinOp,T,D>(MulOpBinOp(MulOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator* (SVector, binary) +//============================================================================== +template <class A, class B, class T, unsigned int D> +inline Expr<BinaryOp<MulOp<T>, Expr<A,T,D>, Expr<B,T,D>, T>, T, D> + operator*(const Expr<A,T,D>& lhs, const Expr<B,T,D>& rhs) { + typedef BinaryOp<MulOp<T>, Expr<A,T,D>, Expr<B,T,D>, T> MulOpBinOp; + + return Expr<MulOpBinOp,T,D>(MulOpBinOp(MulOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator* (SVector, binary, Constant) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<BinaryOp<MulOp<T>, SVector<T,D>, Constant<A>, T>, T, D> + operator*(const SVector<T,D>& lhs, const A& rhs) { + typedef BinaryOp<MulOp<T>, SVector<T,D>, Constant<A>, T> MulOpBinOp; + + return Expr<MulOpBinOp,T,D>(MulOpBinOp(MulOp<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// operator* (SVector, binary, Constant) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<BinaryOp<MulOp<T>, Constant<A>, SVector<T,D>, T>, T, D> + operator*(const A& lhs, const SVector<T,D>& rhs) { + typedef BinaryOp<MulOp<T>, Constant<A>, SVector<T,D>, T> MulOpBinOp; + + return Expr<MulOpBinOp,T,D>(MulOpBinOp(MulOp<T>(),Constant<A>(lhs),rhs)); +} + + +//============================================================================== +// operator* (SVector, binary, Constant) +//============================================================================== +template <class A, class B, class T, unsigned int D> +inline Expr<BinaryOp<MulOp<T>, Expr<B,T,D>, Constant<A>, T>, T, D> + operator*(const Expr<B,T,D>& lhs, const A& rhs) { + typedef BinaryOp<MulOp<T>, Expr<B,T,D>, Constant<A>, T> MulOpBinOp; + + return Expr<MulOpBinOp,T,D>(MulOpBinOp(MulOp<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// operator* (SVector, binary, Constant) +//============================================================================== +template <class A, class B, class T, unsigned int D> +inline Expr<BinaryOp<MulOp<T>, Constant<A>, Expr<B,T,D>, T>, T, D> + operator*(const A& lhs, const Expr<B,T,D>& rhs) { + typedef BinaryOp<MulOp<T>, Constant<A>, Expr<B,T,D>, T> MulOpBinOp; + + return Expr<MulOpBinOp,T,D>(MulOpBinOp(MulOp<T>(),Constant<A>(lhs),rhs)); +} + + +//============================================================================== +// times (SMatrix, binary) +//============================================================================== +template < class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<MulOp<T>, SMatrix<T,D,D2>, SMatrix<T,D,D2>, T>, T, D, D2> + times(const SMatrix<T,D,D2>& lhs, const SMatrix<T,D,D2>& rhs) { + typedef BinaryOp<MulOp<T>, SMatrix<T,D,D2>, SMatrix<T,D,D2>, T> MulOpBinOp; + + return Expr<MulOpBinOp,T,D,D2>(MulOpBinOp(MulOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// times (SMatrix, binary) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<MulOp<T>, Expr<A,T,D,D2>, SMatrix<T,D,D2>, T>, T, D, D2> + times(const Expr<A,T,D,D2>& lhs, const SMatrix<T,D,D2>& rhs) { + typedef BinaryOp<MulOp<T>, Expr<A,T,D,D2>, SMatrix<T,D,D2>, T> MulOpBinOp; + + return Expr<MulOpBinOp,T,D,D2>(MulOpBinOp(MulOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// times (SMatrix, binary) +//============================================================================== +template < class A, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<MulOp<T>, SMatrix<T,D,D2>, Expr<A,T,D,D2>, T>, T, D, D2> + times(const SMatrix<T,D,D2>& lhs, const Expr<A,T,D,D2>& rhs) { + typedef BinaryOp<MulOp<T>, SMatrix<T,D,D2>, Expr<A,T,D,D2>, T> MulOpBinOp; + + return Expr<MulOpBinOp,T,D,D2>(MulOpBinOp(MulOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// times (SMatrix, binary) +//============================================================================== +template <class A, class B, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<MulOp<T>, Expr<A,T,D,D2>, Expr<B,T,D,D2>, T>, T, D, D2> + times(const Expr<A,T,D,D2>& lhs, const Expr<B,T,D,D2>& rhs) { + typedef BinaryOp<MulOp<T>, Expr<A,T,D,D2>, Expr<B,T,D,D2>, T> MulOpBinOp; + + return Expr<MulOpBinOp,T,D,D2>(MulOpBinOp(MulOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator* (SMatrix, binary, Constant) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<MulOp<T>, SMatrix<T,D,D2>, Constant<A>, T>, T, D, D2> + operator*(const SMatrix<T,D,D2>& lhs, const A& rhs) { + typedef BinaryOp<MulOp<T>, SMatrix<T,D,D2>, Constant<A>, T> MulOpBinOp; + + return Expr<MulOpBinOp,T,D,D2>(MulOpBinOp(MulOp<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// operator* (SMatrix, binary, Constant) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<MulOp<T>, Constant<A>, SMatrix<T,D,D2>, T>, T, D, D2> + operator*(const A& lhs, const SMatrix<T,D,D2>& rhs) { + typedef BinaryOp<MulOp<T>, Constant<A>, SMatrix<T,D,D2>, T> MulOpBinOp; + + return Expr<MulOpBinOp,T,D,D2>(MulOpBinOp(MulOp<T>(),Constant<A>(lhs),rhs)); +} + + +//============================================================================== +// operator* (SMatrix, binary, Constant) +//============================================================================== +template <class A, class B, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<MulOp<T>, Expr<B,T,D,D2>, Constant<A>, T>, T, D, D2> + operator*(const Expr<B,T,D,D2>& lhs, const A& rhs) { + typedef BinaryOp<MulOp<T>, Expr<B,T,D,D2>, Constant<A>, T> MulOpBinOp; + + return Expr<MulOpBinOp,T,D,D2>(MulOpBinOp(MulOp<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// operator* (SMatrix, binary, Constant) +//============================================================================== +template <class A, class B, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<MulOp<T>, Constant<A>, Expr<B,T,D,D2>, T>, T, D, D2> + operator*(const A& lhs, const Expr<B,T,D,D2>& rhs) { + typedef BinaryOp<MulOp<T>, Constant<A>, Expr<B,T,D,D2>, T> MulOpBinOp; + + return Expr<MulOpBinOp,T,D,D2>(MulOpBinOp(MulOp<T>(),Constant<A>(lhs),rhs)); +} + + +//============================================================================== +// DivOp +//============================================================================== +template <class T> +class DivOp { +public: + static inline T apply(const T& lhs, const T& rhs) { + return lhs / rhs; + } +}; + + +//============================================================================== +// operator/ (SVector, binary) +//============================================================================== +template < class T, unsigned int D> +inline Expr<BinaryOp<DivOp<T>, SVector<T,D>, SVector<T,D>, T>, T, D> + operator/(const SVector<T,D>& lhs, const SVector<T,D>& rhs) { + typedef BinaryOp<DivOp<T>, SVector<T,D>, SVector<T,D>, T> DivOpBinOp; + + return Expr<DivOpBinOp,T,D>(DivOpBinOp(DivOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator/ (SVector, binary) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<BinaryOp<DivOp<T>, Expr<A,T,D>, SVector<T,D>, T>, T, D> + operator/(const Expr<A,T,D>& lhs, const SVector<T,D>& rhs) { + typedef BinaryOp<DivOp<T>, Expr<A,T,D>, SVector<T,D>, T> DivOpBinOp; + + return Expr<DivOpBinOp,T,D>(DivOpBinOp(DivOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator/ (SVector, binary) +//============================================================================== +template < class A, class T, unsigned int D> +inline Expr<BinaryOp<DivOp<T>, SVector<T,D>, Expr<A,T,D>, T>, T, D> + operator/(const SVector<T,D>& lhs, const Expr<A,T,D>& rhs) { + typedef BinaryOp<DivOp<T>, SVector<T,D>, Expr<A,T,D>, T> DivOpBinOp; + + return Expr<DivOpBinOp,T,D>(DivOpBinOp(DivOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator/ (SVector, binary) +//============================================================================== +template <class A, class B, class T, unsigned int D> +inline Expr<BinaryOp<DivOp<T>, Expr<A,T,D>, Expr<B,T,D>, T>, T, D> + operator/(const Expr<A,T,D>& lhs, const Expr<B,T,D>& rhs) { + typedef BinaryOp<DivOp<T>, Expr<A,T,D>, Expr<B,T,D>, T> DivOpBinOp; + + return Expr<DivOpBinOp,T,D>(DivOpBinOp(DivOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator/ (SVector, binary, Constant) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<BinaryOp<DivOp<T>, SVector<T,D>, Constant<A>, T>, T, D> + operator/(const SVector<T,D>& lhs, const A& rhs) { + typedef BinaryOp<DivOp<T>, SVector<T,D>, Constant<A>, T> DivOpBinOp; + + return Expr<DivOpBinOp,T,D>(DivOpBinOp(DivOp<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// operator/ (SVector, binary, Constant) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<BinaryOp<DivOp<T>, Constant<A>, SVector<T,D>, T>, T, D> + operator/(const A& lhs, const SVector<T,D>& rhs) { + typedef BinaryOp<DivOp<T>, Constant<A>, SVector<T,D>, T> DivOpBinOp; + + return Expr<DivOpBinOp,T,D>(DivOpBinOp(DivOp<T>(),Constant<A>(lhs),rhs)); +} + + +//============================================================================== +// operator/ (SVector, binary, Constant) +//============================================================================== +template <class A, class B, class T, unsigned int D> +inline Expr<BinaryOp<DivOp<T>, Expr<B,T,D>, Constant<A>, T>, T, D> + operator/(const Expr<B,T,D>& lhs, const A& rhs) { + typedef BinaryOp<DivOp<T>, Expr<B,T,D>, Constant<A>, T> DivOpBinOp; + + return Expr<DivOpBinOp,T,D>(DivOpBinOp(DivOp<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// operator/ (SVector, binary, Constant) +//============================================================================== +template <class A, class B, class T, unsigned int D> +inline Expr<BinaryOp<DivOp<T>, Constant<A>, Expr<B,T,D>, T>, T, D> + operator/(const A& lhs, const Expr<B,T,D>& rhs) { + typedef BinaryOp<DivOp<T>, Constant<A>, Expr<B,T,D>, T> DivOpBinOp; + + return Expr<DivOpBinOp,T,D>(DivOpBinOp(DivOp<T>(),Constant<A>(lhs),rhs)); +} + + +//============================================================================== +// operator/ (SMatrix, binary) +//============================================================================== +template < class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<DivOp<T>, SMatrix<T,D,D2>, SMatrix<T,D,D2>, T>, T, D, D2> + operator/(const SMatrix<T,D,D2>& lhs, const SMatrix<T,D,D2>& rhs) { + typedef BinaryOp<DivOp<T>, SMatrix<T,D,D2>, SMatrix<T,D,D2>, T> DivOpBinOp; + + return Expr<DivOpBinOp,T,D,D2>(DivOpBinOp(DivOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator/ (SMatrix, binary) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<DivOp<T>, Expr<A,T,D,D2>, SMatrix<T,D,D2>, T>, T, D, D2> + operator/(const Expr<A,T,D,D2>& lhs, const SMatrix<T,D,D2>& rhs) { + typedef BinaryOp<DivOp<T>, Expr<A,T,D,D2>, SMatrix<T,D,D2>, T> DivOpBinOp; + + return Expr<DivOpBinOp,T,D,D2>(DivOpBinOp(DivOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator/ (SMatrix, binary) +//============================================================================== +template < class A, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<DivOp<T>, SMatrix<T,D,D2>, Expr<A,T,D,D2>, T>, T, D, D2> + operator/(const SMatrix<T,D,D2>& lhs, const Expr<A,T,D,D2>& rhs) { + typedef BinaryOp<DivOp<T>, SMatrix<T,D,D2>, Expr<A,T,D,D2>, T> DivOpBinOp; + + return Expr<DivOpBinOp,T,D,D2>(DivOpBinOp(DivOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator/ (SMatrix, binary) +//============================================================================== +template <class A, class B, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<DivOp<T>, Expr<A,T,D,D2>, Expr<B,T,D,D2>, T>, T, D, D2> + operator/(const Expr<A,T,D,D2>& lhs, const Expr<B,T,D,D2>& rhs) { + typedef BinaryOp<DivOp<T>, Expr<A,T,D,D2>, Expr<B,T,D,D2>, T> DivOpBinOp; + + return Expr<DivOpBinOp,T,D,D2>(DivOpBinOp(DivOp<T>(),lhs,rhs)); +} + + +//============================================================================== +// operator/ (SMatrix, binary, Constant) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<DivOp<T>, SMatrix<T,D,D2>, Constant<A>, T>, T, D, D2> + operator/(const SMatrix<T,D,D2>& lhs, const A& rhs) { + typedef BinaryOp<DivOp<T>, SMatrix<T,D,D2>, Constant<A>, T> DivOpBinOp; + + return Expr<DivOpBinOp,T,D,D2>(DivOpBinOp(DivOp<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// operator/ (SMatrix, binary, Constant) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<DivOp<T>, Constant<A>, SMatrix<T,D,D2>, T>, T, D, D2> + operator/(const A& lhs, const SMatrix<T,D,D2>& rhs) { + typedef BinaryOp<DivOp<T>, Constant<A>, SMatrix<T,D,D2>, T> DivOpBinOp; + + return Expr<DivOpBinOp,T,D,D2>(DivOpBinOp(DivOp<T>(),Constant<A>(lhs),rhs)); +} + + +//============================================================================== +// operator/ (SMatrix, binary, Constant) +//============================================================================== +template <class A, class B, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<DivOp<T>, Expr<B,T,D,D2>, Constant<A>, T>, T, D, D2> + operator/(const Expr<B,T,D,D2>& lhs, const A& rhs) { + typedef BinaryOp<DivOp<T>, Expr<B,T,D,D2>, Constant<A>, T> DivOpBinOp; + + return Expr<DivOpBinOp,T,D,D2>(DivOpBinOp(DivOp<T>(),lhs,Constant<A>(rhs))); +} + +//============================================================================== +// operator/ (SMatrix, binary, Constant) +//============================================================================== +template <class A, class B, class T, unsigned int D, unsigned int D2> +inline Expr<BinaryOp<DivOp<T>, Constant<A>, Expr<B,T,D,D2>, T>, T, D, D2> + operator/(const A& lhs, const Expr<B,T,D,D2>& rhs) { + typedef BinaryOp<DivOp<T>, Constant<A>, Expr<B,T,D,D2>, T> DivOpBinOp; + + return Expr<DivOpBinOp,T,D,D2>(DivOpBinOp(DivOp<T>(),Constant<A>(lhs),rhs)); +} + + + + } // namespace Math + +} // namespace ROOT + + +#endif /*ROOT_Math_BinaryOperators */ diff --git a/smatrix/inc/Math/Dfact.h b/smatrix/inc/Math/Dfact.h new file mode 100644 index 0000000000000000000000000000000000000000..1389519b0d31da05357ec75acbd948faf2b33026 --- /dev/null +++ b/smatrix/inc/Math/Dfact.h @@ -0,0 +1,152 @@ +// @(#)root/smatrix:$Name: $:$Id: Dfact.hv 1.0 2005/11/24 12:00:00 moneta Exp $ +// Authors: T. Glebe, L. Moneta 2005 + +#ifndef ROOT_Math_Dfact +#define ROOT_Math_Dfact +// ******************************************************************** +// +// source: +// +// type: source code +// +// created: 02. Apr 2001 +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +// Description: Determinant of a square matrix +// Code was taken from CERNLIB::kernlib dfact function, translated +// from FORTRAN to C++ and optimized. +// +// changes: +// 02 Apr 2001 (TG) creation +// +// ******************************************************************** + +#include <cmath> + +namespace ROOT { + + namespace Math { + + + +/** Dfact. + Function to compute the determinant from a square matrix ($\det(A)$) of + dimension $idim$ and order $n$. + + @author T. Glebe +*/ +template <class Matrix, unsigned int n, unsigned int idim> +bool Dfact(Matrix& rhs, typename Matrix::value_type& det) { + +#ifdef XXX + if (idim < n || n <= 0) { + return false; + } +#endif + + + /* Initialized data */ + // const typename Matrix::value_type* A = rhs.Array(); + typename Matrix::value_type* a = rhs.Array(); + + /* Local variables */ + static unsigned int nxch, i, j, k, l; + static typename Matrix::value_type p, q, tf; + + /* Parameter adjustments */ + a -= idim + 1; + + /* Function Body */ + + // fact.inc + + nxch = 0; + det = 1.; + for (j = 1; j <= n; ++j) { + const unsigned int ji = j * idim; + const unsigned int jj = j + ji; + + k = j; + p = std::fabs(a[jj]); + + if (j != n) { + for (i = j + 1; i <= n; ++i) { + q = std::fabs(a[i + ji]); + if (q > p) { + k = i; + p = q; + } + } // for i + if (k != j) { + for (l = 1; l <= n; ++l) { + const unsigned int li = l*idim; + const unsigned int jli = j + li; + const unsigned int kli = k + li; + tf = a[jli]; + a[jli] = a[kli]; + a[kli] = tf; + } // for l + ++nxch; + } // if k != j + } // if j!=n + + if (p <= 0.) { + det = 0; + return false; + } + + det *= a[jj]; +#ifdef XXX + t = std::fabs(det); + if (t < 1e-19 || t > 1e19) { + det = 0; + return false; + } +#endif + + a[jj] = 1. / a[jj]; + if (j == n) { + continue; + } + + const unsigned int jm1 = j - 1; + const unsigned int jpi = (j + 1) * idim; + const unsigned int jjpi = j + jpi; + + for (k = j + 1; k <= n; ++k) { + const unsigned int ki = k * idim; + const unsigned int jki = j + ki; + const unsigned int kji = k + jpi; + if (j != 1) { + for (i = 1; i <= jm1; ++i) { + const unsigned int ii = i * idim; + a[jki] -= a[i + ki] * a[j + ii]; + a[kji] -= a[i + jpi] * a[k + ii]; + } // for i + } + a[jki] *= a[jj]; + a[kji] -= a[jjpi] * a[k + ji]; + } // for k + } // for j + + if (nxch % 2 != 0) { + det = -(det); + } + return true; +} // end of Dfact + + + } // namespace Math + +} // namespace ROOT + + + +#endif /* ROOT_Math_Dfact */ diff --git a/smatrix/inc/Math/Dfactir.h b/smatrix/inc/Math/Dfactir.h new file mode 100644 index 0000000000000000000000000000000000000000..be4b6b354a476ae48b04697488b1a99b51ce62ae --- /dev/null +++ b/smatrix/inc/Math/Dfactir.h @@ -0,0 +1,155 @@ +// @(#)root/smatrix:$Name: $:$Id: Dfactir.hv 1.0 2005/11/24 12:00:00 moneta Exp $ +// Authors: T. Glebe, L. Moneta 2005 + +#ifndef ROOT_Math_Dfactir +#define ROOT_Math_Dfactir +// ******************************************************************** +// +// source: +// +// type: source code +// +// created: 02. Apr 2001 +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +// Description: Determinant of a square matrix, needed for Dfinv() +// Code was taken from CERNLIB::kernlib dfact function, translated +// from FORTRAN to C++ and optimized. +// +// changes: +// 02 Apr 2001 (TG) creation +// +// ******************************************************************** + + +namespace ROOT { + + namespace Math { + + +/** Dfactir. + Function to compute the determinant from a square matrix ($\det(A)$) of + dimension $idim$ and order $n$. A working area $ir$ is returned which is + needed by the Dfinv routine. + + @author T. Glebe +*/ +template <class Matrix, unsigned int n, unsigned int idim> +bool Dfactir(Matrix& rhs, typename Matrix::value_type& det, unsigned int* ir) + // int *n, float *a, int *idim, int *ir, int *ifail, float *det, int *jfail) +{ + +#ifdef XXX + if (idim < n || n <= 0) { + return false; + } +#endif + + + /* Initialized data */ + typename Matrix::value_type* a = rhs.Array(); + + /* Local variables */ + static unsigned int nxch, i, j, k, l; + static typename Matrix::value_type p, q, tf; + + /* Parameter adjustments */ + a -= idim + 1; + --ir; + + /* Function Body */ + + // fact.inc + nxch = 0; + det = 1.; + for (j = 1; j <= n; ++j) { + const unsigned int ji = j * idim; + const unsigned int jj = j + ji; + + k = j; + p = std::fabs(a[jj]); + + if (j != n) { + for (i = j + 1; i <= n; ++i) { + q = std::fabs(a[i + ji]); + if (q > p) { + k = i; + p = q; + } + } // for i + + if (k != j) { + for (l = 1; l <= n; ++l) { + const unsigned int li = l*idim; + const unsigned int jli = j + li; + const unsigned int kli = k + li; + tf = a[jli]; + a[jli] = a[kli]; + a[kli] = tf; + } // for l + ++nxch; + ir[nxch] = (j << 12) + k; + } // if k != j + } // if j!=n + + if (p <= 0.) { + det = 0; + return false; + } + + det *= a[jj]; +#ifdef XXX + t = std::fabs(det); + if (t < 1e-19 || t > 1e19) { + det = 0; + return false; + } +#endif + + a[jj] = 1. / a[jj]; + if (j == n) { + continue; + } + + const unsigned int jm1 = j - 1; + const unsigned int jpi = (j + 1) * idim; + const unsigned int jjpi = j + jpi; + + for (k = j + 1; k <= n; ++k) { + const unsigned int ki = k * idim; + const unsigned int jki = j + ki; + const unsigned int kji = k + jpi; + if (j != 1) { + for (i = 1; i <= jm1; ++i) { + const unsigned int ii = i * idim; + a[jki] -= a[i + ki] * a[j + ii]; + a[kji] -= a[i + jpi] * a[k + ii]; + } // for i + } + a[jki] *= a[jj]; + a[kji] -= a[jjpi] * a[k + ji]; + } // for k + } // for j + + if (nxch % 2 != 0) { + det = -(det); + } + ir[n] = nxch; + return true; +} // end of Dfact + + + } // namespace Math + +} // namespace ROOT + + + +#endif /* ROOT_Math_Dfactir */ diff --git a/smatrix/inc/Math/Dfinv.h b/smatrix/inc/Math/Dfinv.h new file mode 100644 index 0000000000000000000000000000000000000000..a6cf0277f217cc307848fa575df85d207bc90c0e --- /dev/null +++ b/smatrix/inc/Math/Dfinv.h @@ -0,0 +1,146 @@ +// @(#)root/smatrix:$Name: $:$Id: Dfinv.hv 1.0 2005/11/24 12:00:00 moneta Exp $ +// Authors: T. Glebe, L. Moneta 2005 + +#ifndef ROOT_Math_Dfinv +#define ROOT_Math_Dfinv +// ******************************************************************** +// +// source: +// +// type: source code +// +// created: 03. Apr 2001 +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +// Description: Matrix inversion +// Code was taken from CERNLIB::kernlib dfinv function, translated +// from FORTRAN to C++ and optimized. +// +// changes: +// 03 Apr 2001 (TG) creation +// +// ******************************************************************** + + +namespace ROOT { + + namespace Math { + + + + +/** Dfinv. + Function to compute the inverse of a square matrix ($A^{-1}$) of + dimension $idim$ and order $n$. The routine Dfactir must be called + before Dfinv! + + @author T. Glebe +*/ +template <class Matrix, unsigned int n, unsigned int idim> +bool Dfinv(Matrix& rhs, unsigned int* ir) { +#ifdef XXX + if (idim < n || n <= 0 || n==1) { + return false; + } +#endif + + typename Matrix::value_type* a = rhs.Array(); + + /* Local variables */ + static unsigned int nxch, i, j, k, m, ij; + static unsigned int im2, nm1, nmi; + static typename Matrix::value_type s31, s34, ti; + + /* Parameter adjustments */ + a -= idim + 1; + --ir; + + /* Function Body */ + + /* finv.inc */ + + a[idim + 2] = -a[(idim << 1) + 2] * (a[idim + 1] * a[idim + 2]); + a[(idim << 1) + 1] = -a[(idim << 1) + 1]; + + if (n != 2) { + for (i = 3; i <= n; ++i) { + const unsigned int ii = i * idim; + const unsigned int iii = i + ii; + const unsigned int imi = ii - idim; + const unsigned int iimi = i + imi; + im2 = i - 2; + for (j = 1; j <= im2; ++j) { + const unsigned int ji = j * idim; + const unsigned int jii = j + ii; + s31 = 0.; + for (k = j; k <= im2; ++k) { + s31 += a[k + ji] * a[i + k * idim]; + a[jii] += a[j + (k + 1) * idim] * a[k + 1 + ii]; + } // for k + a[i + ji] = -a[iii] * (a[i - 1 + ji] * a[iimi] + s31); + a[jii] *= -1; + } // for j + a[iimi] = -a[iii] * (a[i - 1 + imi] * a[iimi]); + a[i - 1 + ii] *= -1; + } // for i + } // if n!=2 + + nm1 = n - 1; + for (i = 1; i <= nm1; ++i) { + const unsigned int ii = i * idim; + nmi = n - i; + for (j = 1; j <= i; ++j) { + const unsigned int ji = j * idim; + const unsigned int iji = i + ji; + for (k = 1; k <= nmi; ++k) { + a[iji] += a[i + k + ji] * a[i + (i + k) * idim]; + } // for k + } // for j + + for (j = 1; j <= nmi; ++j) { + const unsigned int ji = j * idim; + s34 = 0.; + for (k = j; k <= nmi; ++k) { + s34 += a[i + k + ii + ji] * a[i + (i + k) * idim]; + } // for k + a[i + ii + ji] = s34; + } // for j + } // for i + + nxch = ir[n]; + if (nxch == 0) { + return true; + } + + for (m = 1; m <= nxch; ++m) { + k = nxch - m + 1; + ij = ir[k]; + i = ij / 4096; + j = ij % 4096; + const unsigned int ii = i * idim; + const unsigned int ji = j * idim; + for (k = 1; k <= n; ++k) { + ti = a[k + ii]; + a[k + ii] = a[k + ji]; + a[k + ji] = ti; + } // for k + } // for m + + return true; +} // Dfinv + + + } // namespace Math + +} // namespace ROOT + + + +#endif /* ROOT_Math_Dfinv */ diff --git a/smatrix/inc/Math/Dinv.h b/smatrix/inc/Math/Dinv.h new file mode 100644 index 0000000000000000000000000000000000000000..8db4a0d97878dba3b2c3743fe9b46ef881305fb4 --- /dev/null +++ b/smatrix/inc/Math/Dinv.h @@ -0,0 +1,246 @@ +// @(#)root/smatrix:$Name: $:$Id: Dinv.hv 1.0 2005/11/24 12:00:00 moneta Exp $ +// Authors: T. Glebe, L. Moneta 2005 + +#ifndef ROOT_Math_Dinv +#define ROOT_Math_Dinv +// ******************************************************************** +// +// source: +// +// type: source code +// +// created: 03. Apr 2001 +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +// Description: square Matrix inversion +// Code was taken from CERNLIB::kernlib dfinv function, translated +// from FORTRAN to C++ and optimized. +// n: Order of the square matrix +// idim: First dimension of array A +// +// changes: +// 03 Apr 2001 (TG) creation +// +// ******************************************************************** +#include "Math/Dfactir.h" +#include "Math/Dfinv.h" + + + +namespace ROOT { + + namespace Math { + + + +/** Inverter. + Class to specialize calls to Dinv. Dinv computes the inverse of a square + matrix if dimension $idim$ and order $n$. The content of the matrix will be + replaced by its inverse. In case the inversion fails, the matrix content is + destroyed. Invert specializes Dinv by the matrix order. E.g. if the order + of the matrix is two, the routine Invert<2> is called which implements + Cramers rule. + + @author T. Glebe +*/ +//============================================================================== +// Inverter class +//============================================================================== +template <unsigned int idim, unsigned int n = idim> +class Inverter { +public: + /// + template <class Matrix> + static bool Dinv(Matrix& rhs) { + +#ifdef XXX + if (n < 1 || n > idim) { + return false; + } +#endif + + /* Initialized data */ + static unsigned int work[n]; + for(unsigned int i=0; i<n; ++i) work[i] = 0; + + static typename Matrix::value_type det = 0; + + /* Function Body */ + + /* N.GT.3 CASES. FACTORIZE MATRIX AND INVERT. */ + if (Dfactir<Matrix,n,idim>(rhs,det,work) == false) { + std::cerr << "Dfactir failed!!" << std::endl; + return false; + } + return Dfinv<Matrix,n,idim>(rhs,work); + } // Dinv +}; // class Inverter + + +/** Inverter<0>. + In case of zero order, do nothing. + + @author T. Glebe +*/ +//============================================================================== +// Invert<0> +//============================================================================== +template <> +class Inverter<0> { +public: + /// + template <class Matrix> + inline static bool Dinv(Matrix& rhs) { return true; } +}; + + +/** Invert<1>. + $1\times1$ (sub-)matrix. $a_{11} \to 1/a_{11}$ + + @author T. Glebe +*/ +//============================================================================== +// Invert<1> +//============================================================================== +template <> +class Inverter<1> { +public: + /// + template <class Matrix> + static bool Dinv(Matrix& rhs) { + typename Matrix::value_type* a = rhs.Array(); + + if (a[0] == 0.) { + return false; + } + a[0] = 1. / a[0]; + return true; + } +}; + + +/** Invert<2>. + $2\times2$ (sub-)matrix. Use Cramers rule. + + @author T. Glebe +*/ +//============================================================================== +// Invert<2>: Cramers rule +//============================================================================== +template <> +class Inverter<2> { +public: + /// + template <class Matrix> + static bool Dinv(Matrix& rhs) { + + typename Matrix::value_type* a = rhs.Array(); + typename Matrix::value_type det = a[0] * a[3] - a[2] * a[1]; + + if (det == 0.) { return false; } + + typename Matrix::value_type s = 1. / det; + typename Matrix::value_type c11 = s * a[3]; + + a[2] = -s * a[2]; + a[1] = -s * a[1]; + a[3] = s * a[0]; + a[0] = c11; + return true; + } +}; + + +/** Invert<3>. + $3\times3$ (sub-)matrix. Use pivotisation. + + @author T. Glebe +*/ +//============================================================================== +// Inverter<3> +//============================================================================== +template <> +class Inverter<3> { +public: + /// + template <class Matrix> + static bool Dinv(Matrix& rhs) { + + typename Matrix::value_type* a = rhs.Array(); + + static typename Matrix::value_type t1, t2, t3, temp, s; + static typename Matrix::value_type c11, c12, c13, c21, c22, c23, c31, c32, c33, det; + + + /* COMPUTE COFACTORS. */ + c11 = a[4] * a[8] - a[7] * a[5]; + c12 = a[7] * a[2] - a[1] * a[8]; + c13 = a[1] * a[5] - a[4] * a[2]; + c21 = a[5] * a[6] - a[8] * a[3]; + c22 = a[8] * a[0] - a[2] * a[6]; + c23 = a[2] * a[3] - a[5] * a[0]; + c31 = a[3] * a[7] - a[6] * a[4]; + c32 = a[6] * a[1] - a[0] * a[7]; + c33 = a[0] * a[4] - a[3] * a[1]; + + t1 = std::fabs(a[0]); + t2 = std::fabs(a[1]); + t3 = std::fabs(a[2]); + + /* (SET TEMP=PIVOT AND DET=PIVOT*DET.) */ + if(t1 < t2) { + if (t3 < t2) { + /* (PIVOT IS A21) */ + temp = a[1]; + det = c13 * c32 - c12 * c33; + } else { + /* (PIVOT IS A31) */ + temp = a[2]; + det = c23 * c12 - c22 * c13; + } + } else { + if(t3 < t1) { + /* (PIVOT IS A11) */ + temp = a[0]; + det = c22 * c33 - c23 * c32; + } else { + /* (PIVOT IS A31) */ + temp = a[2]; + det = c23 * c12 - c22 * c13; + } + } + + if (det == 0.) { + return false; + } + + /* SET ELEMENTS OF INVERSE IN A. */ + s = temp / det; + a[0] = s * c11; + a[3] = s * c21; + a[6] = s * c31; + a[1] = s * c12; + a[4] = s * c22; + a[7] = s * c32; + a[2] = s * c13; + a[5] = s * c23; + a[8] = s * c33; + return true; + } +}; + + + } // namespace Math + +} // namespace ROOT + + + +#endif /* ROOT_Math_Dinv */ diff --git a/smatrix/inc/Math/Dsfact.h b/smatrix/inc/Math/Dsfact.h new file mode 100644 index 0000000000000000000000000000000000000000..abd6280611591d1a16db96b5b79d5914da92daaa --- /dev/null +++ b/smatrix/inc/Math/Dsfact.h @@ -0,0 +1,112 @@ +// @(#)root/smatrix:$Name: $:$Id: Dsfact.hv 1.0 2005/11/24 12:00:00 moneta Exp $ +// Authors: T. Glebe, L. Moneta 2005 + +#ifndef ROOT_Math_Dsfact +#define ROOT_Math_Dsfact +// ******************************************************************** +// +// source: +// +// type: source code +// +// created: 22. Mar 2001 +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +// Description: Determinant of a symmetric, positive definite matrix. +// Code was taken from CERNLIB::kernlib dsfact function, translated +// from FORTRAN to C++ and optimized. +// +// changes: +// 22 Mar 2001 (TG) creation +// 18 Apr 2001 (TG) removed internal copying of array. +// +// ******************************************************************** + + +namespace ROOT { + + namespace Math { + + + + +/** Dsfact. + Compute determinant of a symmetric, positive definite matrix of dimension + $idim$ and order $n$. + + @author T. Glebe +*/ +template <class Matrix, unsigned int n, unsigned int idim> +bool Dsfact(Matrix& rhs, typename Matrix::value_type& det) { + +#ifdef XXX + /* Function Body */ + if (idim < n || n <= 0) { + return false; + } +#endif + + typename Matrix::value_type* a = rhs.Array(); + +#ifdef XXX + const typename Matrix::value_type* A = rhs.Array(); + typename Matrix::value_type array[Matrix::size]; + typename Matrix::value_type* a = array; + + // copy contents of matrix to working place + for(unsigned int i=0; i<Matrix::size; ++i) { + array[i] = A[i]; + } +#endif + + /* Local variables */ + static unsigned int i, j, l; + + /* Parameter adjustments */ + a -= idim + 1; + + /* sfactd.inc */ + det = 1.; + for (j = 1; j <= n; ++j) { + const unsigned int ji = j * idim; + const unsigned int jj = j + ji; + + if (a[jj] <= 0.) { + det = 0.; + return false; + } + + const unsigned int jp1 = j + 1; + const unsigned int jpi = jp1 * idim; + + det *= a[jj]; + a[jj] = 1. / a[jj]; + + for (l = jp1; l <= n; ++l) { + a[j + l * idim] = a[jj] * a[l + ji]; + + const unsigned int lj = l + jpi; + + for (i = 1; i <= j; ++i) { + a[lj] -= a[l + i * idim] * a[i + jpi]; + } // for i + } // for l + } // for j + + return true; +} // end of Dsfact + + + } // namespace Math + +} // namespace ROOT + +#endif /* ROOT_Math_Dsfact */ + diff --git a/smatrix/inc/Math/Dsinv.h b/smatrix/inc/Math/Dsinv.h new file mode 100644 index 0000000000000000000000000000000000000000..e4b4a13e32ed31fd00893464ded5f926ecb8c066 --- /dev/null +++ b/smatrix/inc/Math/Dsinv.h @@ -0,0 +1,138 @@ +// @(#)root/smatrix:$Name: $:$Id: Dsinv.hv 1.0 2005/11/24 12:00:00 moneta Exp $ +// Authors: T. Glebe, L. Moneta 2005 + +#ifndef ROOT_Math_Dsinv +#define ROOT_Math_Dsinv +// ******************************************************************** +// +// source: +// +// type: source code +// +// created: 22. Mar 2001 +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +// Description: Inversion of a symmetric, positive definite matrix. +// Code was taken from CERNLIB::kernlib dsinv function, translated +// from FORTRAN to C++ and optimized. +// +// changes: +// 22 Mar 2001 (TG) creation +// +// ******************************************************************** + + +namespace ROOT { + + namespace Math { + +/** Dsinv. + Compute inverse of a symmetric, positive definite matrix of dimension + $idim$ and order $n$. + + @author T. Glebe +*/ +template <class T, int n, int idim> +bool Dsinv(T* a) { + + /* Local variables */ + static int i, j, k, l; + static T s31, s32; + static int jm1, jp1; + + /* Parameter adjustments */ + a -= idim + 1; + + /* Function Body */ + if (idim < n || n <= 1) { + return false; + } + + /* sfact.inc */ + for (j = 1; j <= n; ++j) { + const int ja = j * idim; + const int jj = j + ja; + const int ja1 = ja + idim; + + if (a[jj] <= 0.) { return false; } + a[jj] = 1. / a[jj]; + if (j == n) { break; } + + for (l = j + 1; l <= n; ++l) { + a[j + l * idim] = a[jj] * a[l + ja]; + const int lj = l + ja1; + for (i = 1; i <= j; ++i) { + a[lj] -= a[l + i * idim] * a[i + ja1]; + } + } + } + + /* sfinv.inc */ + // idim << 1 is equal to idim * 2 + // compiler will compute the arguments! + a[(idim << 1) + 1] = -a[(idim << 1) + 1]; + a[idim + 2] = a[(idim << 1) + 1] * a[(idim << 1) + 2]; + + if(n > 2) { + + for (j = 3; j <= n; ++j) { + const int jm2 = j - 2; + const int ja = j * idim; + const int jj = j + ja; + const int j1 = j - 1 + ja; + + for (k = 1; k <= jm2; ++k) { + s31 = a[k + ja]; + + for (i = k; i <= jm2; ++i) { + s31 += a[k + (i + 1) * idim] * a[i + 1 + ja]; + } // for i + a[k + ja] = -s31; + a[j + k * idim] = -s31 * a[jj]; + } // for k + a[j1] *= -1; + // a[j1] = -a[j1]; + a[jj - idim] = a[j1] * a[jj]; + } // for j + } // if (n>2) + + j = 1; + do { + const int jad = j * idim; + const int jj = j + jad; + + jp1 = j + 1; + for (i = jp1; i <= n; ++i) { + a[jj] += a[j + i * idim] * a[i + jad]; + } // for i + + jm1 = j; + j = jp1; + const int ja = j * idim; + + for (k = 1; k <= jm1; ++k) { + s32 = 0.; + for (i = j; i <= n; ++i) { + s32 += a[k + i * idim] * a[i + ja]; + } // for i + a[k + ja] = a[j + k * idim] = s32; + } // for k + } while(j < n); + + return true; +} // end of Dsinv + + + } // namespace Math + +} // namespace ROOT + + +#endif /* ROOT_Math_Dsinv */ diff --git a/smatrix/inc/Math/Expression.h b/smatrix/inc/Math/Expression.h new file mode 100644 index 0000000000000000000000000000000000000000..cc29e7c5d1a3b7f1d613865b848c2549ee203bef --- /dev/null +++ b/smatrix/inc/Math/Expression.h @@ -0,0 +1,240 @@ +// @(#)root/smatrix:$Name: $:$Id: Expression.hv 1.0 2005/11/24 12:00:00 moneta Exp $ +// Authors: T. Glebe, L. Moneta 2005 + +#ifndef ROOT_Math_Expression +#define ROOT_Math_Expression +// ******************************************************************** +// +// source: +// +// type: source code +// +// created: 19. Mar 2001 +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +// Description: Expression Template Elements for SVector +// +// changes: +// 19 Mar 2001 (TG) creation +// 20 Mar 2001 (TG) added rows(), cols() to Expr +// 21 Mar 2001 (TG) added Expr::value_type +// 11 Apr 2001 (TG) rows(), cols() replaced by rows, cols +// 10 Okt 2001 (TG) added print() and operator<<() for Expr class +// +// ******************************************************************** + +/** Expr. + An Expression wrapper class. + + @memo Expr. + @author T. Glebe +*/ +//============================================================================== +// Expr: class representing SVector expressions +//============================================================================= + +// originally references where used as data members of operation wrappers +// problem appear on Windows because original ref goes out of scope use then by value by default (like in tvmet) +//#define SMATRIX_USE_REFERENCES + + +#include <iomanip> + + +namespace ROOT { + + namespace Math { + + + +template <class ExprType, class T, unsigned int D, unsigned int D2 = 0> +class Expr { +public: + typedef T value_type; + + /// + Expr(const ExprType& rhs) : + rhs_(rhs) {} + + /// + ~Expr() {} + + /// + inline T apply(unsigned int i) const { + return rhs_.apply(i); + } + +#ifdef OLD_IMPL + /// + static const unsigned int rows = D; + /// + static const unsigned int cols = D2; +#else + // use enumerations + enum { + /// + rows = D, + /// + cols = D2, + }; +#endif + + /// used by operator<<() + std::ostream& print(std::ostream& os) const { + os.setf(std::ios::right,std::ios::adjustfield); + + if(D2 == 0) { + unsigned int i=0; + for(; i<D-1; ++i) { + os << apply(i) << ", "; + } + os << apply(i); + } else { + os << "[ "; + for (unsigned int i=0; i < D; ++i) { + for (unsigned int j=0; j < D2; ++j) { + os << std::setw(12) << apply(i*D2+j); + if ((!((j+1)%12)) && (j < D2-1)) + os << std::endl << " ..."; + } + if (i != D - 1) + os << std::endl << " "; + } + os << " ]"; + } // if D2==0 + + return os; + } + +private: + ExprType rhs_; // cannot be a reference! +}; + +//============================================================================== +// operator<< +//============================================================================== +template <class A, class T, unsigned int D1, unsigned int D2> +inline std::ostream& operator<<(std::ostream& os, const Expr<A,T,D1,D2>& rhs) { + return rhs.print(os); +} + +/** BinaryOp. + A class representing binary operators in the parse tree. + + @memo BinaryOp + @author T. Glebe +*/ +//============================================================================== +// BinaryOp +//============================================================================== +template <class Operator, class LHS, class RHS, class T> +class BinaryOp { +public: + /// + BinaryOp( Operator /* op */, const LHS& lhs, const RHS& rhs) : + lhs_(lhs), rhs_(rhs) {} + + /// + ~BinaryOp() {} + + /// + inline T apply(unsigned int i) const { + return Operator::apply(lhs_.apply(i), rhs_.apply(i)); + } + +protected: + +#ifdef SMATRIX_USE_REFERENCES + const LHS& lhs_; + const RHS& rhs_; +#else + const LHS lhs_; + const RHS rhs_; +#endif + +}; + + +/** UnaryOp. + A class representing unary operators in the parse tree. + + @memo UnaryOp + @author T. Glebe +*/ +//============================================================================== +// UnaryOp +//============================================================================== +template <class Operator, class RHS, class T> +class UnaryOp { +public: + /// + UnaryOp( Operator /* op */ , const RHS& rhs) : + rhs_(rhs) {} + + /// + ~UnaryOp() {} + + /// + inline T apply(unsigned int i) const { + return Operator::apply(rhs_.apply(i)); + } + +protected: + +#ifdef SMATRIX_USE_REFERENCES + const RHS& rhs_; +#else + const RHS rhs_; +#endif + +}; + + +/** Constant. + A class representing constant expressions (literals) in the parse tree. + + @memo Constant + @author T. Glebe +*/ +//============================================================================== +// Constant +//============================================================================== +template <class T> +class Constant { +public: + /// + Constant( const T& rhs ) : + rhs_(rhs) {} + + /// + ~Constant() {} + + /// + inline T apply(unsigned int /*i */ ) const { return rhs_; } + +protected: + +#ifdef SMATRIX_USE_REFERENCES + const T& rhs_; +#else + const T rhs_; +#endif + +}; + + + + } // namespace Math + +} // namespace ROOT + + + +#endif /* ROOT_Math_Expression */ diff --git a/smatrix/inc/Math/Functions.h b/smatrix/inc/Math/Functions.h new file mode 100644 index 0000000000000000000000000000000000000000..ace5fb9de74d440c5eabe2443d3da2fa9bae1fe9 --- /dev/null +++ b/smatrix/inc/Math/Functions.h @@ -0,0 +1,392 @@ +// @(#)root/smatrix:$Name: $:$Id: Functions.hv 1.0 2005/11/24 12:00:00 moneta Exp $ +// Authors: T. Glebe, L. Moneta 2005 + +#ifndef ROOT_Math_Functions +#define ROOT_Math_Functions +// ******************************************************************** +// +// source: +// +// type: source code +// +// created: 16. Mar 2001 +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +// Description: Functions which are not applied like a unary operator +// +// changes: +// 16 Mar 2001 (TG) creation +// 03 Apr 2001 (TG) minimum added, doc++ comments added +// 07 Apr 2001 (TG) Lmag2, Lmag added +// 19 Apr 2001 (TG) added #include <cmath> +// 24 Apr 2001 (TG) added sign() +// 26 Jul 2001 (TG) round() added +// 27 Sep 2001 (TG) added Expr declaration +// +// ******************************************************************** +#include <cmath> +#include "Math/Expression.h" + + +namespace ROOT { + + namespace Math { + + + +template <class T, unsigned int D> class SVector; + + +/** square. + Template to compute $x\cdot x$ + + @author T. Glebe +*/ +//============================================================================== +// square: x*x +//============================================================================== +template <class T> +inline const T Square(const T& x) { return x*x; } + +/** maximum. + Template to compute $\max(i,j)$ + + @author T. Glebe +*/ +//============================================================================== +// maximum +//============================================================================== +template <class T> +inline const T Maximum(const T& lhs, const T& rhs) { + return (lhs > rhs) ? lhs : rhs; +} + +/** minimum. + Template to compute $\min(i,j)$ + + @author T. Glebe +*/ +//============================================================================== +// minimum +//============================================================================== +template <class T> +inline const T Minimum(const T& lhs, const T& rhs) { + return (lhs < rhs) ? lhs : rhs; +} + +/** round. + Template to compute nearest integer value. + + @author T. Glebe +*/ +//============================================================================== +// round +//============================================================================== +template <class T> +inline int Round(const T& x) { + return (x-static_cast<int>(x) < 0.5) ? static_cast<int>(x) : static_cast<int>(x+1); +} + + +/** sign. + Template to compute the sign of a number $\textrm{sgn}(i)$. + + @author T. Glebe +*/ +//============================================================================== +// sign +//============================================================================== +template <class T> +inline const int Sign(const T& x) { return (x==0)? 0 : (x<0)? -1 : 1; } + +//============================================================================== +// meta_dot +//============================================================================== +template <unsigned int I> +struct meta_dot { + template <class A, class B, class T> + static inline T f(const A& lhs, const B& rhs, const T& x) { + return lhs.apply(I) * rhs.apply(I) + meta_dot<I-1>::f(lhs,rhs,x); + } +}; + + +//============================================================================== +// meta_dot<0> +//============================================================================== +template <> +struct meta_dot<0> { + template <class A, class B, class T> + static inline T f(const A& lhs, const B& rhs, const T& /*x */) { + return lhs.apply(0) * rhs.apply(0); + } +}; + + +/** dot. + Template to compute $\vec{a}\cdot\vec{b} = \sum_i a_i\cdot b_i$. + + @author T. Glebe +*/ +//============================================================================== +// dot +//============================================================================== +template <class T, unsigned int D> +inline T Dot(const SVector<T,D>& lhs, const SVector<T,D>& rhs) { + return meta_dot<D-1>::f(lhs,rhs, T()); +} + +//============================================================================== +// dot +//============================================================================== +template <class A, class T, unsigned int D> +inline T Dot(const SVector<T,D>& lhs, const Expr<A,T,D>& rhs) { + return meta_dot<D-1>::f(lhs,rhs, T()); +} + +//============================================================================== +// dot +//============================================================================== +template <class A, class T, unsigned int D> +inline T Dot(const Expr<A,T,D>& lhs, const SVector<T,D>& rhs) { + return meta_dot<D-1>::f(lhs,rhs, T()); +} + + +//============================================================================== +// dot +//============================================================================== +template <class A, class B, class T, unsigned int D> +inline T Dot(const Expr<A,T,D>& lhs, const Expr<B,T,D>& rhs) { + return meta_dot<D-1>::f(rhs,lhs, T()); +} + + +//============================================================================== +// meta_mag +//============================================================================== +template <unsigned int I> +struct meta_mag { + template <class A, class T> + static inline T f(const A& rhs, const T& x) { + return Square(rhs.apply(I)) + meta_mag<I-1>::f(rhs, x); + } +}; + + +//============================================================================== +// meta_mag<0> +//============================================================================== +template <> +struct meta_mag<0> { + template <class A, class T> + static inline T f(const A& rhs, const T& ) { + return Square(rhs.apply(0)); + } +}; + + +/** mag2. + Template to compute $|\vec{v}|^2 = \sum_iv_i^2$. + + @author T. Glebe +*/ +//============================================================================== +// mag2 +//============================================================================== +template <class T, unsigned int D> +inline T Mag2(const SVector<T,D>& rhs) { + return meta_mag<D-1>::f(rhs, T()); +} + +//============================================================================== +// mag2 +//============================================================================== +template <class A, class T, unsigned int D> +inline T Mag2(const Expr<A,T,D>& rhs) { + return meta_mag<D-1>::f(rhs, T()); +} + +/** mag. + Length of a vector: $|\vec{v}| = \sqrt{\sum_iv_i^2}$. + + @author T. Glebe +*/ +//============================================================================== +// mag +//============================================================================== +template <class T, unsigned int D> +inline T Mag(const SVector<T,D>& rhs) { + return std::sqrt(Mag2(rhs)); +} + +//============================================================================== +// mag +//============================================================================== +template <class A, class T, unsigned int D> +inline T Mag(const Expr<A,T,D>& rhs) { + return std::sqrt(Mag2(rhs)); +} + + +/** Lmag2. + Template to compute $|\vec{v}|^2 = v_0^2 - v_1^2 - v_2^2 -v_3^2$. + + @author T. Glebe +*/ +//============================================================================== +// Lmag2 +//============================================================================== +template <class T> +inline T Lmag2(const SVector<T,4>& rhs) { + return Square(rhs[0]) - Square(rhs[1]) - Square(rhs[2]) - Square(rhs[3]); +} + +//============================================================================== +// Lmag2 +//============================================================================== +template <class A, class T> +inline T Lmag2(const Expr<A,T,4>& rhs) { + return Square(rhs.apply(0)) + - Square(rhs.apply(1)) - Square(rhs.apply(2)) - Square(rhs.apply(3)); +} + +/** Lmag. + Length of a vector Lorentz-Vector: $|\vec{v}| = \sqrt{v_0^2 - + v_1^2 - v_2^2 -v_3^2}$. + + @author T. Glebe +*/ +//============================================================================== +// Lmag +//============================================================================== +template <class T> +inline T Lmag(const SVector<T,4>& rhs) { + return std::sqrt(Lmag2(rhs)); +} + +//============================================================================== +// Lmag +//============================================================================== +template <class A, class T> +inline T Lmag(const Expr<A,T,4>& rhs) { + return std::sqrt(Lmag2(rhs)); +} + + +/** cross. + Cross product of two 3-dim vectors: $\vec{c} = \vec{a}\times\vec{b}$. + + @author T. Glebe +*/ +//============================================================================== +// cross product +//============================================================================== +template <class T> +inline SVector<T,3> Cross(const SVector<T,3>& lhs, const SVector<T,3>& rhs) { + return SVector<T,3>(lhs.apply(1)*rhs.apply(2) - + lhs.apply(2)*rhs.apply(1), + lhs.apply(2)*rhs.apply(0) - + lhs.apply(0)*rhs.apply(2), + lhs.apply(0)*rhs.apply(1) - + lhs.apply(1)*rhs.apply(0)); +} + +//============================================================================== +// cross product +//============================================================================== +template <class A, class T> +inline SVector<T,3> Cross(const Expr<A,T,3>& lhs, const SVector<T,3>& rhs) { + return SVector<T,3>(lhs.apply(1)*rhs.apply(2) - + lhs.apply(2)*rhs.apply(1), + lhs.apply(2)*rhs.apply(0) - + lhs.apply(0)*rhs.apply(2), + lhs.apply(0)*rhs.apply(1) - + lhs.apply(1)*rhs.apply(0)); +} + +//============================================================================== +// cross product +//============================================================================== +template <class T, class A> +inline SVector<T,3> Cross(const SVector<T,3>& lhs, const Expr<A,T,3>& rhs) { + return SVector<T,3>(lhs.apply(1)*rhs.apply(2) - + lhs.apply(2)*rhs.apply(1), + lhs.apply(2)*rhs.apply(0) - + lhs.apply(0)*rhs.apply(2), + lhs.apply(0)*rhs.apply(1) - + lhs.apply(1)*rhs.apply(0)); +} + +//============================================================================== +// cross product +//============================================================================== +template <class A, class B, class T> +inline SVector<T,3> Cross(const Expr<A,T,3>& lhs, const Expr<B,T,3>& rhs) { + return SVector<T,3>(lhs.apply(1)*rhs.apply(2) - + lhs.apply(2)*rhs.apply(1), + lhs.apply(2)*rhs.apply(0) - + lhs.apply(0)*rhs.apply(2), + lhs.apply(0)*rhs.apply(1) - + lhs.apply(1)*rhs.apply(0)); +} + + +/** Unit. + Return a vector of unit lenght: $\vec{e}_v = \vec{v}/|\vec{v}|$. + + @author T. Glebe +*/ +//============================================================================== +// unit: returns a unit vector +//============================================================================== +template <class T, unsigned int D> +inline SVector<T,D> Unit(const SVector<T,D>& rhs) { + return SVector<T,D>(rhs).Unit(); +} + +//============================================================================== +// unit: returns a unit vector +//============================================================================== +template <class A, class T, unsigned int D> +inline SVector<T,D> Unit(const Expr<A,T,D>& rhs) { + return SVector<T,D>(rhs).Unit(); +} + +#ifdef XXX +//============================================================================== +// unit: returns a unit vector (worse performance) +//============================================================================== +template <class T, unsigned int D> +inline Expr<BinaryOp<DivOp<T>, SVector<T,D>, Constant<T>, T>, T, D> + unit(const SVector<T,D>& lhs) { + typedef BinaryOp<DivOp<T>, SVector<T,D>, Constant<T>, T> DivOpBinOp; + return Expr<DivOpBinOp,T,D>(DivOpBinOp(DivOp<T>(),lhs,Constant<T>(mag(lhs)))); +} + +//============================================================================== +// unit: returns a unit vector (worse performance) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<BinaryOp<DivOp<T>, Expr<A,T,D>, Constant<T>, T>, T, D> + unit(const Expr<A,T,D>& lhs) { + typedef BinaryOp<DivOp<T>, Expr<A,T,D>, Constant<T>, T> DivOpBinOp; + return Expr<DivOpBinOp,T,D>(DivOpBinOp(DivOp<T>(),lhs,Constant<T>(mag(lhs)))); +} +#endif + + + } // namespace Math + +} // namespace ROOT + + + +#endif /* ROOT_Math_Functions */ diff --git a/smatrix/inc/Math/MConfig.h b/smatrix/inc/Math/MConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..1b2ef6a3365c1fa06f9e5a67a3b52cb49ca5b991 --- /dev/null +++ b/smatrix/inc/Math/MConfig.h @@ -0,0 +1,21 @@ +// @(#)root/smatrix:$Name: $:$Id: MConfig.hv 1.0 2005/11/24 12:00:00 moneta Exp $ +// Authors: T. Glebe, L. Moneta 2005 + +#ifndef ROOT_Math_MConfig_ +#define ROOT_Math_MConfig + +// for alpha streams +#if defined(__alpha) && !defined(linux) +# include <standards.h> +# ifndef __USE_STD_IOSTREAM +# define __USE_STD_IOSTREAM +# endif +#endif + + +#if defined(__sun) && !defined(linux) +#include <stdlib.h> +#endif + + +#endif diff --git a/smatrix/inc/Math/MatrixFunctions.h b/smatrix/inc/Math/MatrixFunctions.h new file mode 100644 index 0000000000000000000000000000000000000000..ad2c93b9bcb6b6596a7f5c6abc0b23f5055e575b --- /dev/null +++ b/smatrix/inc/Math/MatrixFunctions.h @@ -0,0 +1,528 @@ +// @(#)root/smatrix:$Name: $:$Id: MatrixFunctions.hv 1.0 2005/11/24 12:00:00 moneta Exp $ +// Authors: T. Glebe, L. Moneta 2005 + +#ifndef ROOT_Math_MatrixFunctions +#define ROOT_Math_MatrixFunctions +// ******************************************************************** +// +// source: +// +// type: source code +// +// created: 20. Mar 2001 +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +// Description: Functions/Operators special to Matrix +// +// changes: +// 20 Mar 2001 (TG) creation +// 20 Mar 2001 (TG) Added Matrix * Vector multiplication +// 21 Mar 2001 (TG) Added transpose, product +// 11 Apr 2001 (TG) transpose() speed improvment by removing rows(), cols() +// through static members of Matrix and Expr class +// +// ******************************************************************** + + + +namespace ROOT { + + namespace Math { + + + +#ifdef XXX +//============================================================================== +// SMatrix * SVector +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +SVector<T,D1> operator*(const SMatrix<T,D1,D2>& rhs, const SVector<T,D2>& lhs) +{ + SVector<T,D1> tmp; + for(unsigned int i=0; i<D1; ++i) { + const unsigned int rpos = i*D2; + for(unsigned int j=0; j<D2; ++j) { + tmp[i] += rhs.apply(rpos+j) * lhs.apply(j); + } + } + return tmp; +} +#endif + + +//============================================================================== +// meta_row_dot +//============================================================================== +template <unsigned int I> +struct meta_row_dot { + template <class A, class B> + static inline typename A::value_type f(const A& lhs, const B& rhs, + const unsigned int offset) { + return lhs.apply(offset+I) * rhs.apply(I) + meta_row_dot<I-1>::f(lhs,rhs,offset); + } +}; + + +//============================================================================== +// meta_row_dot<0> +//============================================================================== +template <> +struct meta_row_dot<0> { + template <class A, class B> + static inline typename A::value_type f(const A& lhs, const B& rhs, + const unsigned int offset) { + return lhs.apply(offset) * rhs.apply(0); + } +}; + +//============================================================================== +// VectorMatrixRowOp +//============================================================================== +template <class Matrix, class Vector, unsigned int D2> +class VectorMatrixRowOp { +public: + /// + VectorMatrixRowOp(const Matrix& lhs, const Vector& rhs) : + lhs_(lhs), rhs_(rhs) {} + + /// + ~VectorMatrixRowOp() {} + + /// calc $\sum_{j} a_{ij} * v_j$ + inline typename Matrix::value_type apply(unsigned int i) const { + return meta_row_dot<D2-1>::f(lhs_, rhs_, i*D2); + } + +protected: + const Matrix& lhs_; + const Vector& rhs_; +}; + + +//============================================================================== +// meta_col_dot +//============================================================================== +template <unsigned int I> +struct meta_col_dot { + template <class Matrix, class Vector> + static inline typename Matrix::value_type f(const Matrix& lhs, const Vector& rhs, + const unsigned int offset) { + return lhs.apply(Matrix::cols*I+offset) * rhs.apply(I) + + meta_col_dot<I-1>::f(lhs,rhs,offset); + } +}; + + +//============================================================================== +// meta_col_dot<0> +//============================================================================== +template <> +struct meta_col_dot<0> { + template <class Matrix, class Vector> + static inline typename Matrix::value_type f(const Matrix& lhs, const Vector& rhs, + const unsigned int offset) { + return lhs.apply(offset) * rhs.apply(0); + } +}; + +//============================================================================== +// VectorMatrixColOp +//============================================================================== +template <class Vector, class Matrix, unsigned int D1> +class VectorMatrixColOp { +public: + /// + VectorMatrixColOp(const Vector& lhs, const Matrix& rhs) : + lhs_(lhs), rhs_(rhs) {} + + /// + ~VectorMatrixColOp() {} + + /// calc $\sum_{j} a_{ij} * v_j$ + inline typename Matrix::value_type apply(unsigned int i) const { + return meta_col_dot<D1-1>::f(rhs_, lhs_, i); + } + +protected: + const Vector& lhs_; + const Matrix& rhs_; +}; + +//============================================================================== +// operator*: SMatrix * SVector +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +inline Expr<VectorMatrixRowOp<SMatrix<T,D1,D2>,SVector<T,D2>, D2>, T, D1> + operator*(const SMatrix<T,D1,D2>& lhs, const SVector<T,D2>& rhs) { + + typedef VectorMatrixRowOp<SMatrix<T,D1,D2>,SVector<T,D2>, D2> VMOp; + return Expr<VMOp, T, D1>(VMOp(lhs,rhs)); +} + +//============================================================================== +// operator*: SMatrix * Expr<A,T,D2> +//============================================================================== +template <class A, class T, unsigned int D1, unsigned int D2> +inline Expr<VectorMatrixRowOp<SMatrix<T,D1,D2>, Expr<A,T,D2>, D2>, T, D1> + operator*(const SMatrix<T,D1,D2>& lhs, const Expr<A,T,D2>& rhs) { + + typedef VectorMatrixRowOp<SMatrix<T,D1,D2>,Expr<A,T,D2>, D2> VMOp; + return Expr<VMOp, T, D1>(VMOp(lhs,rhs)); +} + +//============================================================================== +// operator*: Expr<A,T,D1,D2> * SVector +//============================================================================== +template <class A, class T, unsigned int D1, unsigned int D2> +inline Expr<VectorMatrixRowOp<Expr<A,T,D1,D2>, SVector<T,D2>, D2>, T, D1> + operator*(const Expr<A,T,D1,D2>& lhs, const SVector<T,D2>& rhs) { + + typedef VectorMatrixRowOp<Expr<A,T,D1,D2>,SVector<T,D2>, D2> VMOp; + return Expr<VMOp, T, D1>(VMOp(lhs,rhs)); +} + +//============================================================================== +// operator*: Expr<A,T,D1,D2> * Expr<B,T,D2> +//============================================================================== +template <class A, class B, class T, unsigned int D1, unsigned int D2> +inline Expr<VectorMatrixRowOp<Expr<A,T,D1,D2>, Expr<B,T,D2>, D2>, T, D1> + operator*(const Expr<A,T,D1,D2>& lhs, const Expr<B,T,D2>& rhs) { + + typedef VectorMatrixRowOp<Expr<A,T,D1,D2>,Expr<B,T,D2>, D2> VMOp; + return Expr<VMOp, T, D1>(VMOp(lhs,rhs)); +} + +//============================================================================== +// operator*: SVector * SMatrix +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +inline Expr<VectorMatrixColOp<SVector<T,D1>, SMatrix<T,D1,D2>, D1>, T, D2> + operator*(const SVector<T,D1>& lhs, const SMatrix<T,D1,D2>& rhs) { + + typedef VectorMatrixColOp<SVector<T,D1>, SMatrix<T,D1,D2>, D1> VMOp; + return Expr<VMOp, T, D2>(VMOp(lhs,rhs)); +} + +//============================================================================== +// operator*: SVector * Expr<A,T,D1,D2> +//============================================================================== +template <class A, class T, unsigned int D1, unsigned int D2> +inline Expr<VectorMatrixColOp<SVector<T,D1>, Expr<A,T,D1,D2>, D1>, T, D2> + operator*(const SVector<T,D1>& lhs, const Expr<A,T,D1,D2>& rhs) { + + typedef VectorMatrixColOp<SVector<T,D1>, Expr<A,T,D1,D2>, D1> VMOp; + return Expr<VMOp, T, D2>(VMOp(lhs,rhs)); +} + +//============================================================================== +// operator*: Expr<A,T,D1> * SMatrix +//============================================================================== +template <class A, class T, unsigned int D1, unsigned int D2> +inline Expr<VectorMatrixColOp<Expr<A,T,D1>, SMatrix<T,D1,D2>, D1>, T, D2> + operator*(const Expr<A,T,D1>& lhs, const SMatrix<T,D1,D2>& rhs) { + + typedef VectorMatrixColOp<Expr<A,T,D1>, SMatrix<T,D1,D2>, D1> VMOp; + return Expr<VMOp, T, D2>(VMOp(lhs,rhs)); +} + +//============================================================================== +// operator*: Expr<A,T,D1> * Expr<B,T,D1,D2> +//============================================================================== +template <class A, class B, class T, unsigned int D1, unsigned int D2> +inline Expr<VectorMatrixColOp<Expr<A,T,D1>, Expr<B,T,D1,D2>, D1>, T, D2> + operator*(const Expr<A,T,D1>& lhs, const Expr<B,T,D1,D2>& rhs) { + + typedef VectorMatrixColOp<Expr<A,T,D1>, Expr<B,T,D1,D2>, D1> VMOp; + return Expr<VMOp, T, D2>(VMOp(lhs,rhs)); +} + +//============================================================================== +// meta_matrix_dot +//============================================================================== +template <unsigned int I> +struct meta_matrix_dot { + template <class MatrixA, class MatrixB> + static inline typename MatrixA::value_type f(const MatrixA& lhs, const MatrixB& rhs, + const unsigned int offset) { + return lhs.apply(offset/MatrixB::cols*MatrixA::cols + I) * + rhs.apply(MatrixB::cols*I + offset%MatrixB::cols) + + meta_matrix_dot<I-1>::f(lhs,rhs,offset); + } +}; + + +//============================================================================== +// meta_matrix_dot<0> +//============================================================================== +template <> +struct meta_matrix_dot<0> { + template <class MatrixA, class MatrixB> + static inline typename MatrixA::value_type f(const MatrixA& lhs, const MatrixB& rhs, + const unsigned int offset) { + return lhs.apply(offset/MatrixB::cols*MatrixA::cols) * + rhs.apply(offset%MatrixB::cols); + } +}; + +//============================================================================== +// MatrixMulOp +//============================================================================== +template <class MatrixA, class MatrixB, class T, unsigned int D> +class MatrixMulOp { +public: + /// + MatrixMulOp(const MatrixA& lhs, const MatrixB& rhs) : + lhs_(lhs), rhs_(rhs) {} + + /// + ~MatrixMulOp() {} + + /// calc $\sum_{j} a_{ik} * b_{kj}$ + inline T apply(unsigned int i) const { + return meta_matrix_dot<D-1>::f(lhs_, rhs_, i); + } + +protected: + const MatrixA& lhs_; + const MatrixB& rhs_; +}; + + +//============================================================================== +// operator* (SMatrix * SMatrix, binary) +//============================================================================== +template < class T, unsigned int D1, unsigned int D, unsigned int D2> +inline Expr<MatrixMulOp<SMatrix<T,D1,D>, SMatrix<T,D,D2>,T,D>, T, D1, D2> + operator*(const SMatrix<T,D1,D>& lhs, const SMatrix<T,D,D2>& rhs) { + typedef MatrixMulOp<SMatrix<T,D1,D>, SMatrix<T,D,D2>, T,D> MatMulOp; + + return Expr<MatMulOp,T,D1,D2>(MatMulOp(lhs,rhs)); +} + +//============================================================================== +// operator* (SMatrix * Expr, binary) +//============================================================================== +template <class A, class T, unsigned int D1, unsigned int D, unsigned int D2> +inline Expr<MatrixMulOp<SMatrix<T,D1,D>, Expr<A,T,D,D2>,T,D>, T, D1, D2> + operator*(const SMatrix<T,D1,D>& lhs, const Expr<A,T,D,D2>& rhs) { + typedef MatrixMulOp<SMatrix<T,D1,D>, Expr<A,T,D,D2>,T,D> MatMulOp; + + return Expr<MatMulOp,T,D1,D2>(MatMulOp(lhs,rhs)); +} + +//============================================================================== +// operator* (Expr * SMatrix, binary) +//============================================================================== +template <class A, class T, unsigned int D1, unsigned int D, unsigned int D2> +inline Expr<MatrixMulOp<Expr<A,T,D1,D>, SMatrix<T,D,D2>,T,D>, T, D1, D2> + operator*(const Expr<A,T,D1,D>& lhs, const SMatrix<T,D,D2>& rhs) { + typedef MatrixMulOp<Expr<A,T,D1,D>, SMatrix<T,D,D2>,T,D> MatMulOp; + + return Expr<MatMulOp,T,D1,D2>(MatMulOp(lhs,rhs)); +} + +//============================================================================== +// operator* (Expr * Expr, binary) +//============================================================================== +template <class A, class B, class T, unsigned int D1, unsigned int D, unsigned int D2> +inline Expr<MatrixMulOp<Expr<A,T,D1,D>, Expr<B,T,D,D2>,T,D>, T, D1, D2> + operator*(const Expr<A,T,D1,D>& lhs, const Expr<B,T,D,D2>& rhs) { + typedef MatrixMulOp<Expr<A,T,D1,D>, Expr<B,T,D,D2>, T,D> MatMulOp; + + return Expr<MatMulOp,T,D1,D2>(MatMulOp(lhs,rhs)); +} + + +#ifdef XXX +//============================================================================== +// MatrixMulOp +//============================================================================== +template <class MatrixA, class MatrixB, unsigned int D> +class MatrixMulOp { +public: + /// + MatrixMulOp(const MatrixA& lhs, const MatrixB& rhs) : + lhs_(lhs), rhs_(rhs) {} + + /// + ~MatrixMulOp() {} + + /// calc $\sum_{j} a_{ik} * b_{kj}$ + inline typename MatrixA::value_type apply(unsigned int i) const { + return meta_matrix_dot<D-1>::f(lhs_, rhs_, i); + } + +protected: + const MatrixA& lhs_; + const MatrixB& rhs_; +}; + + +//============================================================================== +// operator* (SMatrix * SMatrix, binary) +//============================================================================== +template < class T, unsigned int D1, unsigned int D, unsigned int D2> +inline Expr<MatrixMulOp<SMatrix<T,D1,D>, SMatrix<T,D,D2>, D>, T, D1, D2> + operator*(const SMatrix<T,D1,D>& lhs, const SMatrix<T,D,D2>& rhs) { + typedef MatrixMulOp<SMatrix<T,D1,D>, SMatrix<T,D,D2>, D> MatMulOp; + + return Expr<MatMulOp,T,D1,D2>(MatMulOp(lhs,rhs)); +} + +//============================================================================== +// operator* (SMatrix * Expr, binary) +//============================================================================== +template <class A, class T, unsigned int D1, unsigned int D, unsigned int D2> +inline Expr<MatrixMulOp<SMatrix<T,D1,D>, Expr<A,T,D,D2>, D>, T, D1, D2> + operator*(const SMatrix<T,D1,D>& lhs, const Expr<A,T,D,D2>& rhs) { + typedef MatrixMulOp<SMatrix<T,D1,D>, Expr<A,T,D,D2>, D> MatMulOp; + + return Expr<MatMulOp,T,D1,D2>(MatMulOp(lhs,rhs)); +} + +//============================================================================== +// operator* (Expr * SMatrix, binary) +//============================================================================== +template <class A, class T, unsigned int D1, unsigned int D, unsigned int D2> +inline Expr<MatrixMulOp<Expr<A,T,D1,D>, SMatrix<T,D,D2>, D>, T, D1, D2> + operator*(const Expr<A,T,D1,D>& lhs, const SMatrix<T,D,D2>& rhs) { + typedef MatrixMulOp<Expr<A,T,D1,D>, SMatrix<T,D,D2>, D> MatMulOp; + + return Expr<MatMulOp,T,D1,D2>(MatMulOp(lhs,rhs)); +} + +//============================================================================== +// operator* (Expr * Expr, binary) +//============================================================================== +template <class A, class B, class T, unsigned int D1, unsigned int D, unsigned int D2> +inline Expr<MatrixMulOp<Expr<A,T,D1,D>, Expr<B,T,D,D2>, D>, T, D1, D2> + operator*(const Expr<A,T,D1,D>& lhs, const Expr<B,T,D,D2>& rhs) { + typedef MatrixMulOp<Expr<A,T,D1,D>, Expr<B,T,D,D2>, D> MatMulOp; + + return Expr<MatMulOp,T,D1,D2>(MatMulOp(lhs,rhs)); +} +#endif + +//============================================================================== +// TransposeOp +//============================================================================== +template <class Matrix, class T, unsigned int D1, unsigned int D2=D1> +class TransposeOp { +public: + /// + TransposeOp( const Matrix& rhs) : + rhs_(rhs) {} + + /// + ~TransposeOp() {} + + /// + inline T apply(unsigned int i) const { + return rhs_.apply( (i%D1)*D2 + i/D1); + } + +protected: + const Matrix& rhs_; +}; + + +//============================================================================== +// transpose +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +inline Expr<TransposeOp<SMatrix<T,D1,D2>,T,D1,D2>, T, D2, D1> + transpose(const SMatrix<T,D1,D2>& rhs) { + typedef TransposeOp<SMatrix<T,D1,D2>,T,D1,D2> MatTrOp; + + return Expr<MatTrOp, T, D2, D1>(MatTrOp(rhs)); +} + +//============================================================================== +// transpose +//============================================================================== +template <class A, class T, unsigned int D1, unsigned int D2> +inline Expr<TransposeOp<Expr<A,T,D1,D2>,T,D1,D2>, T, D2, D1> + transpose(const Expr<A,T,D1,D2>& rhs) { + typedef TransposeOp<Expr<A,T,D1,D2>,T,D1,D2> MatTrOp; + + return Expr<MatTrOp, T, D2, D1>(MatTrOp(rhs)); +} + +//============================================================================== +// product: SMatrix/SVector calculate v^T * A * v +//============================================================================== +template <class T, unsigned int D> +inline T Product(const SMatrix<T,D>& lhs, const SVector<T,D>& rhs) { + return Dot(rhs, lhs * rhs); +} + +//============================================================================== +// product: SVector/SMatrix calculate v^T * A * v +//============================================================================== +template <class T, unsigned int D> +inline T Product(const SVector<T,D>& lhs, const SMatrix<T,D>& rhs) { + return Dot(lhs, rhs * lhs); +} + +//============================================================================== +// product: SMatrix/Expr calculate v^T * A * v +//============================================================================== +template <class A, class T, unsigned int D> +inline T Product(const SMatrix<T,D>& lhs, const Expr<A,T,D>& rhs) { + return Dot(rhs, lhs * rhs); +} + +//============================================================================== +// product: Expr/SMatrix calculate v^T * A * v +//============================================================================== +template <class A, class T, unsigned int D> +inline T Product(const Expr<A,T,D>& lhs, const SMatrix<T,D>& rhs) { + return Dot(lhs, rhs * lhs); +} + +//============================================================================== +// product: SVector/Expr calculate v^T * A * v +//============================================================================== +template <class A, class T, unsigned int D> +inline T Product(const SVector<T,D>& lhs, const Expr<A,T,D,D>& rhs) { + return Dot(lhs, rhs * lhs); +} + +//============================================================================== +// product: Expr/SVector calculate v^T * A * v +//============================================================================== +template <class A, class T, unsigned int D> +inline T Product(const Expr<A,T,D,D>& lhs, const SVector<T,D>& rhs) { + return Dot(rhs, lhs * rhs); +} + +//============================================================================== +// product: Expr/Expr calculate v^T * A * v +//============================================================================== +template <class A, class B, class T, unsigned int D> +inline T Product(const Expr<A,T,D,D>& lhs, const Expr<B,T,D>& rhs) { + return Dot(rhs, lhs * rhs); +} + +//============================================================================== +// product: Expr/Expr calculate v^T * A * v +//============================================================================== +template <class A, class B, class T, unsigned int D> +inline T Product(const Expr<A,T,D>& lhs, const Expr<B,T,D,D>& rhs) { + return Dot(lhs, rhs * lhs); +} + + + } // namespace Math + +} // namespace ROOT + + +#endif /* ROOT_Math_MatrixFunctions */ diff --git a/smatrix/inc/Math/SMatrix.h b/smatrix/inc/Math/SMatrix.h new file mode 100644 index 0000000000000000000000000000000000000000..f7adaf532b451cabd35acbeed9edec57a571bafc --- /dev/null +++ b/smatrix/inc/Math/SMatrix.h @@ -0,0 +1,281 @@ +// @(#)root/smatrix:$Name: $:$Id: SMatrix.hv 1.0 2005/11/24 12:00:00 moneta Exp $ +// Authors: T. Glebe, L. Moneta 2005 + +#ifndef ROOT_Math_SMatrix +#define ROOT_Math_SMatrix +// ******************************************************************** +// +// source: +// +// type: source code +// +// created: 20. Mar 2001 +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +// Description: A fixed size two dimensional Matrix class +// +// changes: +// 20 Mar 2001 (TG) creation +// 21 Mar 2001 (TG) added operators +=, -=, *=, /= +// 26 Mar 2001 (TG) place_in_row(), place_in_col() added +// 02 Apr 2001 (TG) non-const Array() added +// 03 Apr 2001 (TG) invert() added +// 07 Apr 2001 (TG) CTOR from SVertex (dyadic product) added +// 09 Apr 2001 (TG) CTOR from array added +// 11 Apr 2001 (TG) rows(), cols(), size() replaced by rows, cols, size +// 25 Mai 2001 (TG) row(), col() added +// 04 Sep 2001 (TG) moved inlined functions to .icc file +// 11 Jan 2002 (TG) added operator==(), operator!=() +// 14 Jan 2002 (TG) added more operator==(), operator!=(), operator>(), operator<() +// +// ******************************************************************** +// for platform specific configurations +#include "Math/MConfig.h" + +#include <iosfwd> + + +// expression engine + +#include "Math/Expression.h" + + +namespace ROOT { + + namespace Math { + + template <class T, unsigned int D> class SVector; + + + + +/** SMatrix. + A generic fixed size n x m Matrix class.q + + @memo SMatrix + @author T. Glebe +*/ +//============================================================================== +// SMatrix: column-wise storage +//============================================================================== +template <class T, unsigned int D1, unsigned int D2 = D1> +class SMatrix { +public: + /** @name --- Typedefs --- */ + /// + typedef T value_type; + + /** @name --- Constructors --- */ + /// + SMatrix(); + /// + SMatrix(const SMatrix<T,D1,D2>& rhs); + /// + template <class A> + SMatrix(const Expr<A,T,D1,D2>& rhs); + + // skip this methods (they are too ambigous) +#ifdef OLD_IMPL + /// 2nd arg: set only diagonal? + SMatrix(const T& rhs, const bool diagonal=false); + /// constructor via dyadic product + SMatrix(const SVector<T,D1>& rhs); + /// constructor via dyadic product + template <class A> + SMatrix(const Expr<A,T,D1>& rhs); + + /** constructor via array, triag=true: array contains only upper/lower + triangular part of a symmetric matrix, len: length of array */ + template <class T1> + //SMatrix(const T1* a, const bool triang=false, const unsigned int len=D1*D2); + // to avoid clash with TRootIOconst + SMatrix(const T1* a, const bool triang, const unsigned int len=D1*D2); + + + /// assign from a scalar value + SMatrix<T,D1,D2>& operator=(const T& rhs); +#endif + + /// + template <class A> + SMatrix<T,D1,D2>& operator=(const Expr<A,T,D1,D2>& rhs); + + +#ifdef OLD_IMPL + /// return no. of matrix rows + static const unsigned int rows = D1; + /// return no. of matrix columns + static const unsigned int cols = D2; + /// return no of elements: rows*columns + static const unsigned int size = D1*D2; +#else + enum { + /// return no. of matrix rows + rows = D1, + /// return no. of matrix columns + cols = D2, + /// return no of elements: rows*columns + size = D1*D2 + }; +#endif + /** @name --- Access functions --- */ + /// access the parse tree + T apply(unsigned int i) const; + /// return read-only pointer to internal array + const T* Array() const; + /// return pointer to internal array + T* Array(); + + /** @name --- Operators --- */ + /// element wise comparison + bool operator==(const T& rhs) const; + /// element wise comparison + bool operator!=(const T& rhs) const; + /// element wise comparison + bool operator==(const SMatrix<T,D1,D2>& rhs) const; + /// element wise comparison + bool operator!=(const SMatrix<T,D1,D2>& rhs) const; + /// element wise comparison + template <class A> + bool operator==(const Expr<A,T,D1,D2>& rhs) const; + /// element wise comparison + template <class A> + bool operator!=(const Expr<A,T,D1,D2>& rhs) const; + + /// element wise comparison + bool operator>(const T& rhs) const; + /// element wise comparison + bool operator<(const T& rhs) const; + /// element wise comparison + bool operator>(const SMatrix<T,D1,D2>& rhs) const; + /// element wise comparison + bool operator<(const SMatrix<T,D1,D2>& rhs) const; + /// element wise comparison + template <class A> + bool operator>(const Expr<A,T,D1,D2>& rhs) const; + /// element wise comparison + template <class A> + bool operator<(const Expr<A,T,D1,D2>& rhs) const; + + /// read-only access + const T& operator()(unsigned int i, unsigned int j) const; + /// read/write access + T& operator()(unsigned int i, unsigned int j); + + /// + SMatrix<T,D1,D2>& operator+=(const SMatrix<T,D1,D2>& rhs); + + SMatrix<T,D1,D2>& operator-=(const SMatrix<T,D1,D2>& rhs); + + SMatrix<T,D1,D2>& operator*=(const SMatrix<T,D1,D2>& rhs); + + SMatrix<T,D1,D2>& operator/=(const SMatrix<T,D1,D2>& rhs); + + +#ifndef __CINT__ + /// + template <class A> + SMatrix<T,D1,D2>& operator+=(const Expr<A,T,D1,D2>& rhs); + /// + /// + template <class A> + SMatrix<T,D1,D2>& operator-=(const Expr<A,T,D1,D2>& rhs); + /// + /// + template <class A> + SMatrix<T,D1,D2>& operator*=(const Expr<A,T,D1,D2>& rhs); + /// + /// + template <class A> + SMatrix<T,D1,D2>& operator/=(const Expr<A,T,D1,D2>& rhs); + +#endif + + /** @name --- Expert functions --- */ + /// invert symmetric, pos. def. Matrix via Dsinv + bool Sinvert(); + /** determinant of symmetrc, pos. def. Matrix via Dsfact. \textbf{Note:} this + will destroy the contents of the Matrix!*/ + bool Sdet(T& det); + /// invert square Matrix via Dinv + bool Invert(); + /** determinant of square Matrix via Dfact. \textbf{Note:} this will destroy + the contents of the Matrix! */ + bool Det(T& det); + /// place a vector in a Matrix row + template <unsigned int D> + SMatrix<T,D1,D2>& Place_in_row(const SVector<T,D>& rhs, + const unsigned int row, + const unsigned int col); + /// place a vector expression in a Matrix row + template <class A, unsigned int D> + SMatrix<T,D1,D2>& Place_in_row(const Expr<A,T,D>& rhs, + const unsigned int row, + const unsigned int col); + /// place a vector in a Matrix column + template <unsigned int D> + SMatrix<T,D1,D2>& Place_in_col(const SVector<T,D>& rhs, + const unsigned int row, + const unsigned int col); + /// place a vector expression in a Matrix column + template <class A, unsigned int D> + SMatrix<T,D1,D2>& Place_in_col(const Expr<A,T,D>& rhs, + const unsigned int row, + const unsigned int col); + /// place a matrix in this matrix + template <unsigned int D3, unsigned int D4> + SMatrix<T,D1,D2>& Place_at(const SMatrix<T,D3,D4>& rhs, + const unsigned int row, + const unsigned int col); + /// place a matrix expression in this matrix + template <class A, unsigned int D3, unsigned int D4> + SMatrix<T,D1,D2>& Place_at(const Expr<A,T,D3,D4>& rhs, + const unsigned int row, + const unsigned int col); + /// return a Matrix row as a vector + SVector<T,D2> Row(const unsigned int therow) const; + /// return a Matrix column as a vector + SVector<T,D1> Col(const unsigned int thecol) const; + /// used by operator<<() + std::ostream& Print(std::ostream& os) const; + +private: + T fArray[D1*D2]; +}; // end of class SMatrix + + + +//============================================================================== +// operator<< +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +inline std::ostream& operator<<(std::ostream& os, const ROOT::Math::SMatrix<T,D1,D2>& rhs) { + return rhs.Print(os); +} + + + } // namespace Math + +} // namespace ROOT + + + + + + +#ifndef __CINT__ + +#include "Math/SMatrix.icc" +// include Matrix-Vector multiplication +#include "Math/MatrixFunctions.h" + +#endif //__CINT__ + +#endif /* ROOT_Math_SMatrix */ diff --git a/smatrix/inc/Math/SMatrix.icc b/smatrix/inc/Math/SMatrix.icc new file mode 100644 index 0000000000000000000000000000000000000000..0c306ba0f8df1662db0ddb8c01099bdd16be4edf --- /dev/null +++ b/smatrix/inc/Math/SMatrix.icc @@ -0,0 +1,597 @@ +// @(#)root/smatrix:$Name: $:$Id: SMatrix.iccv 1.0 2005/11/24 12:00:00 moneta Exp $ +// Authors: T. Glebe, L. Moneta 2005 + +#ifndef ROOT_Math_SMatrix_icc +#define ROOT_Math_SMatrix_icc +// ******************************************************************** +// +// source: +// +// type: source code +// +// created: 21. Mar 2001 +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +// Description: SMatrix implementation file +// +// changes: +// 21 Mar 2001 (TG) creation +// 26 Mar 2001 (TG) place_in_row(), place_in_col() added +// 03 Apr 2001 (TG) invert() added +// 07 Apr 2001 (TG) CTOR from SVertex (dyadic product) added +// 09 Apr 2001 (TG) CTOR from array added +// 25 Mai 2001 (TG) row(), col() added +// 11 Jul 2001 (TG) added #include Functions.hh +// 11 Jan 2002 (TG) added operator==(), operator!=() +// 14 Jan 2002 (TG) added more operator==(), operator!=(), operator>(), operator<() +// +// ******************************************************************** +#include <iostream> +#include <iomanip> +#include <assert.h> +#include "Math/Dsinv.h" +#include "Math/Dsfact.h" +#include "Math/Dfact.h" +#include "Math/Dinv.h" +#include "Math/Functions.h" + + +namespace ROOT { + + namespace Math { + + + +//============================================================================== +// Constructors +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +SMatrix<T,D1,D2>::SMatrix() { + // operator=(0); // if operator=(T ) is defined + for(unsigned int i=0; i<D1*D2; ++i) { + fArray[i] = 0; + } +} + +template <class T, unsigned int D1, unsigned int D2> +SMatrix<T,D1,D2>::SMatrix(const SMatrix<T,D1,D2>& rhs) { + for(unsigned int i=0; i<D1*D2; ++i) { + fArray[i] = rhs.fArray[i]; + } +} + +template <class T, unsigned int D1, unsigned int D2> +template <class A> +SMatrix<T,D1,D2>::SMatrix(const Expr<A,T,D1,D2>& rhs) { + operator=(rhs); +} + +#ifdef OLD_IMPL + +template <class T, unsigned int D1, unsigned int D2> +SMatrix<T,D1,D2>::SMatrix(const T& rhs, const bool diagonal) { + if(diagonal) { + // symmetric matrix! + assert(D1==D2); + // 50% faster than with nested loops + for(unsigned int i=0; i<D1*D2; ++i) + fArray[i] = 0; + for(unsigned int i=0; i<D1; ++i) + fArray[i*D1+i] = rhs; + } else { + for(unsigned int i=0; i<D1*D2; ++i) { + fArray[i] = rhs; + } + } +} + +template <class T, unsigned int D1, unsigned int D2> +SMatrix<T,D1,D2>::SMatrix(const SVector<T,D1>& rhs) { + for(unsigned int i=0; i<D1; ++i) { + const unsigned int row = i*D1; + for(unsigned int j=0; j<D1; ++j) { + fArray[row+j] = rhs[i]*rhs[j]; + } + } +} + +template <class T, unsigned int D1, unsigned int D2> +template <class A> +SMatrix<T,D1,D2>::SMatrix(const Expr<A,T,D1>& rhs) { + for(unsigned int i=0; i<D1; ++i) { + const unsigned int row = i*D1; + for(unsigned int j=0; j<D1; ++j) { + fArray[row+j] = rhs.apply(i)*rhs.apply(j); + } + } +} + +template <class T, unsigned int D1, unsigned int D2> +template <class T1> +SMatrix<T,D1,D2>::SMatrix(const T1* a, const bool triang, const unsigned int len) { + // fill from array with lower triangular matrix? + if(triang==false) { + for(unsigned int i=0; i<len; ++i) { + fArray[i] = a[i]; + } + if(len<D1*D2) + for(unsigned int i=len; i<D1*D2; ++i) + fArray[i] = 0.; + } else { + // symmetric matrix required! + assert(D1==D2); + + unsigned int k=0; + if(len == (Square(D1)+D1)/2) { + for(unsigned int i=0; i<D1; ++i) { + const unsigned int row = i*D1; + for(unsigned int j=0; j<=i && k<len; ++j) { + fArray[row+j] = fArray[j*D1+i] = a[k++]; + } + } + } else { + unsigned int k=0; + for(unsigned int i=0; i<D1; ++i) { + const unsigned int row = i*D1; + for(unsigned int j=0; j<=i; ++j) { + if(k<len) + fArray[row+j] = fArray[j*D1+i] = a[k++]; + else + fArray[row+j] = fArray[j*D1+i] = 0.; + } // for j + } // for i + } // if len == + } // if triang +} + + +//============================================================================== +// operator= +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +SMatrix<T,D1,D2>& SMatrix<T,D1,D2>::operator=(const T& rhs) { + for(unsigned int i=0; i<D1*D2; ++i) { + fArray[i] = rhs; + } + return *this; +} + +#endif + + +template <class T, unsigned int D1, unsigned int D2> +template <class A> +SMatrix<T,D1,D2>& SMatrix<T,D1,D2>::operator=(const Expr<A,T,D1,D2>& rhs) { + for(unsigned int i=0; i<D1*D2; ++i) { + fArray[i] = rhs.apply(i); + } + return *this; +} + + +//============================================================================== +// operator+= +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +SMatrix<T,D1,D2>& SMatrix<T,D1,D2>::operator+=(const SMatrix<T,D1,D2>& rhs) { + for(unsigned int i=0; i<D1*D2; ++i) { + fArray[i] += rhs.apply(i); + } + return *this; +} + +template <class T, unsigned int D1, unsigned int D2> +template <class A> +SMatrix<T,D1,D2>& SMatrix<T,D1,D2>::operator+=(const Expr<A,T,D1,D2>& rhs) { + for(unsigned int i=0; i<D1*D2; ++i) { + fArray[i] += rhs.apply(i); + } + return *this; +} + + +//============================================================================== +// operator-= +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +SMatrix<T,D1,D2>& SMatrix<T,D1,D2>::operator-=(const SMatrix<T,D1,D2>& rhs) { + for(unsigned int i=0; i<D1*D2; ++i) { + fArray[i] -= rhs.apply(i); + } + return *this; +} + +template <class T, unsigned int D1, unsigned int D2> +template <class A> +SMatrix<T,D1,D2>& SMatrix<T,D1,D2>::operator-=(const Expr<A,T,D1,D2>& rhs) { + for(unsigned int i=0; i<D1*D2; ++i) { + fArray[i] -= rhs.apply(i); + } + return *this; +} + + +//============================================================================== +// operator*= +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +SMatrix<T,D1,D2>& SMatrix<T,D1,D2>::operator*=(const SMatrix<T,D1,D2>& rhs) { + for(unsigned int i=0; i<D1*D2; ++i) { + fArray[i] *= rhs.apply(i); + } + return *this; +} + +template <class T, unsigned int D1, unsigned int D2> +template <class A> +SMatrix<T,D1,D2>& SMatrix<T,D1,D2>::operator*=(const Expr<A,T,D1,D2>& rhs) { + for(unsigned int i=0; i<D1*D2; ++i) { + fArray[i] *= rhs.apply(i); + } + return *this; +} + + +//============================================================================== +// operator/= +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +SMatrix<T,D1,D2>& SMatrix<T,D1,D2>::operator/=(const SMatrix<T,D1,D2>& rhs) { + for(unsigned int i=0; i<D1*D2; ++i) { + fArray[i] /= rhs.apply(i); + } + return *this; +} + +template <class T, unsigned int D1, unsigned int D2> +template <class A> +SMatrix<T,D1,D2>& SMatrix<T,D1,D2>::operator/=(const Expr<A,T,D1,D2>& rhs) { + for(unsigned int i=0; i<D1*D2; ++i) { + fArray[i] /= rhs.apply(i); + } + return *this; +} + + +//============================================================================== +// operator== (element wise comparison) +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +bool SMatrix<T,D1,D2>::operator==(const T& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D1*D2; ++i) { + rc = rc && (fArray[i] == rhs); + } + return rc; +} + +template <class T, unsigned int D1, unsigned int D2> +bool SMatrix<T,D1,D2>::operator==(const SMatrix<T,D1,D2>& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D1*D2; ++i) { + rc = rc && (fArray[i] == rhs.fArray[i]); + } + return rc; +} + +template <class T, unsigned int D1, unsigned int D2> +template <class A> +bool SMatrix<T,D1,D2>::operator==(const Expr<A,T,D1,D2>& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D1*D2; ++i) { + rc = rc && (fArray[i] == rhs.apply(i)); + } + return rc; +} + +//============================================================================== +// operator!= (element wise comparison) +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +inline bool SMatrix<T,D1,D2>::operator!=(const T& rhs) const { + return !operator==(rhs); +} + +template <class T, unsigned int D1, unsigned int D2> +inline bool SMatrix<T,D1,D2>::operator!=(const SMatrix<T,D1,D2>& rhs) const { + return !operator==(rhs); +} + +template <class T, unsigned int D1, unsigned int D2> +template <class A> +inline bool SMatrix<T,D1,D2>::operator!=(const Expr<A,T,D1,D2>& rhs) const { + return !operator==(rhs); +} + + +//============================================================================== +// operator> (element wise comparison) +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +bool SMatrix<T,D1,D2>::operator>(const T& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D1*D2; ++i) { + rc = rc && (fArray[i] > rhs); + } + return rc; +} + +template <class T, unsigned int D1, unsigned int D2> +bool SMatrix<T,D1,D2>::operator>(const SMatrix<T,D1,D2>& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D1*D2; ++i) { + rc = rc && (fArray[i] > rhs.fArray[i]); + } + return rc; +} + +template <class T, unsigned int D1, unsigned int D2> +template <class A> +bool SMatrix<T,D1,D2>::operator>(const Expr<A,T,D1,D2>& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D1*D2; ++i) { + rc = rc && (fArray[i] > rhs.apply(i)); + } + return rc; +} + +//============================================================================== +// operator< (element wise comparison) +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +bool SMatrix<T,D1,D2>::operator<(const T& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D1*D2; ++i) { + rc = rc && (fArray[i] < rhs); + } + return rc; +} + +template <class T, unsigned int D1, unsigned int D2> +bool SMatrix<T,D1,D2>::operator<(const SMatrix<T,D1,D2>& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D1*D2; ++i) { + rc = rc && (fArray[i] < rhs.fArray[i]); + } + return rc; +} + +template <class T, unsigned int D1, unsigned int D2> +template <class A> +bool SMatrix<T,D1,D2>::operator<(const Expr<A,T,D1,D2>& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D1*D2; ++i) { + rc = rc && (fArray[i] < rhs.apply(i)); + } + return rc; +} + +//============================================================================== +// sinvert +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +inline bool SMatrix<T,D1,D2>::Sinvert() { + return Dsinv<T,D1,D1>(fArray); +} + +//============================================================================== +// sdet +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +inline bool SMatrix<T,D1,D2>::Sdet(T& det) { + return Dsfact<SMatrix<T,D1,D1>, D1, D1>(*this,det); +} + +//============================================================================== +// invert +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +inline bool SMatrix<T,D1,D2>::Invert() { + return Inverter<D2>::Dinv(*this); +} + +//============================================================================== +// det +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +inline bool SMatrix<T,D1,D2>::Det(T& det) { + return Dfact<SMatrix<T,D1,D1>, D1, D1>(*this,det); +} + +//============================================================================== +// place_in_row +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +template <unsigned int D> +SMatrix<T,D1,D2>& SMatrix<T,D1,D2>::Place_in_row(const SVector<T,D>& rhs, + const unsigned int row, + const unsigned int col) { + + assert(col+D <= D2); + + for(unsigned int i=row*D2+col, j=0; j<D; ++i, ++j) { + fArray[i] = rhs.apply(j); + } + return *this; +} + +//============================================================================== +// place_in_row +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +template <class A, unsigned int D> +SMatrix<T,D1,D2>& SMatrix<T,D1,D2>::Place_in_row(const Expr<A,T,D>& rhs, + const unsigned int row, + const unsigned int col) { + + assert(col+D <= D2); + + for(unsigned int i=row*D2+col, j=0; j<D; ++i, ++j) { + fArray[i] = rhs.apply(j); + } + return *this; +} + +//============================================================================== +// place_in_col +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +template <unsigned int D> +SMatrix<T,D1,D2>& SMatrix<T,D1,D2>::Place_in_col(const SVector<T,D>& rhs, + const unsigned int row, + const unsigned int col) { + + assert(row+D <= D1); + + for(unsigned int i=row*D2+col, j=0; j<D; i+=D2, ++j) { + fArray[i] = rhs.apply(j); + } + return *this; +} + +//============================================================================== +// place_in_col +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +template <class A, unsigned int D> +SMatrix<T,D1,D2>& SMatrix<T,D1,D2>::Place_in_col(const Expr<A,T,D>& rhs, + const unsigned int row, + const unsigned int col) { + + assert(row+D <= D1); + + for(unsigned int i=row*D2+col, j=0; j<D; i+=D2, ++j) { + fArray[i] = rhs.apply(j); + } + return *this; +} + +//============================================================================== +// place_at +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +template <unsigned int D3, unsigned int D4> +SMatrix<T,D1,D2>& SMatrix<T,D1,D2>::Place_at(const SMatrix<T,D3,D4>& rhs, + const unsigned int row, + const unsigned int col) { + assert(row+D3 <= D1 && col+D4 <= D2); + + const unsigned int offset = row*D2+col; + + for(unsigned int i=0; i<D3*D4; ++i) { + fArray[offset+(i/D4)*D2+i%D4] = rhs.apply(i); + } + + return *this; +} + +//============================================================================== +// place_at +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +template <class A, unsigned int D3, unsigned int D4> +SMatrix<T,D1,D2>& SMatrix<T,D1,D2>::Place_at(const Expr<A,T,D3,D4>& rhs, + const unsigned int row, + const unsigned int col) { + assert(row+D3 <= D1 && col+D4 <= D2); + + const unsigned int offset = row*D2+col; + + for(unsigned int i=0; i<D3*D4; ++i) { + fArray[offset+(i/D4)*D2+i%D4] = rhs.apply(i); + } + + return *this; +} + +//============================================================================== +// row +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +SVector<T,D2> SMatrix<T,D1,D2>::Row(const unsigned int therow) const { + + const unsigned int offset = therow*D2; + + static SVector<T,D2> tmp; + for(unsigned int i=0; i<D2; ++i) { + tmp[i] = fArray[offset+i]; + } + return tmp; +} + +//============================================================================== +// col +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +SVector<T,D1> SMatrix<T,D1,D2>::Col(const unsigned int thecol) const { + + static SVector<T,D1> tmp; + for(unsigned int i=0; i<D1; ++i) { + tmp[i] = fArray[thecol+i*D2]; + } + return tmp; +} + +//============================================================================== +// print +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +std::ostream& SMatrix<T,D1,D2>::Print(std::ostream& os) const { + os.setf(std::ios::right,std::ios::adjustfield); + // os.setf(ios::fixed); + + os << "[ "; + for (unsigned int i=0; i < D1; ++i) { + for (unsigned int j=0; j < D2; ++j) { + os << std::setw(12) << fArray[i*D2+j]; + if ((!((j+1)%12)) && (j < D2-1)) + os << std::endl << " ..."; + } + if (i != D1 - 1) + os << std::endl << " "; + } + os << " ]"; + + return os; +} + +//============================================================================== +// Access functions +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +inline T SMatrix<T,D1,D2>::apply(unsigned int i) const { return fArray[i]; } + +template <class T, unsigned int D1, unsigned int D2> +inline const T* SMatrix<T,D1,D2>::Array() const { return fArray; } + +template <class T, unsigned int D1, unsigned int D2> +inline T* SMatrix<T,D1,D2>::Array() { return fArray; } + +//============================================================================== +// Operators +//============================================================================== +template <class T, unsigned int D1, unsigned int D2> +inline const T& SMatrix<T,D1,D2>::operator()(unsigned int i, unsigned int j) const { + return fArray[i*D2+j]; +} + +template <class T, unsigned int D1, unsigned int D2> +inline T& SMatrix<T,D1,D2>::operator()(unsigned int i, unsigned int j) { + return fArray[i*D2+j]; +} + + + } // namespace Math + +} // namespace ROOT + + + +#endif diff --git a/smatrix/inc/Math/SVector.h b/smatrix/inc/Math/SVector.h new file mode 100644 index 0000000000000000000000000000000000000000..57ea4909d3485575f35aee110d7d7dbd71dd0e06 --- /dev/null +++ b/smatrix/inc/Math/SVector.h @@ -0,0 +1,242 @@ +// @(#)root/smatrix:$Name: $:$Id: SVector.hv 1.0 2005/11/24 12:00:00 moneta Exp $ +// Authors: T. Glebe, L. Moneta 2005 + +#ifndef ROOT_Math_SVector +#define ROOT_Math_SVector +// ******************************************************************** +// +// source: +// +// type: source code +// +// created: 16. Mar 2001 +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +// Description: A fixed size Vector class +// +// changes: +// 16 Mar 2001 (TG) creation +// 21 Mar 2001 (TG) SVector::value_type added +// 21 Mar 2001 (TG) added operators +=, -=, *=, /= +// 26 Mar 2001 (TG) added place_at() +// 03 Apr 2001 (TG) Array() added +// 06 Apr 2001 (TG) CTORS added +// 07 Apr 2001 (TG) CTORS added +// 22 Aug 2001 (TG) CTOR(T*,len) added +// 04 Sep 2001 (TG) moved inlined functions to .icc file +// 14 Jan 2002 (TG) added operator==(), operator!=(), operator>(), operator<() +// +// ******************************************************************** + +#include "Math/MConfig.h" + +#include <iosfwd> + + +// expression engine +#include "Math/Expression.h" + + + +namespace ROOT { + + namespace Math { + + template <class A, class T, unsigned int D, unsigned int D2> class Expr; + + +/** SVector. + A generic fixed size Vector class. + + @memo SVector + @author T. Glebe +*/ +//============================================================================== +// SVector +//============================================================================== +template <class T, unsigned int D> +class SVector { +public: + /** @name --- Typedefs --- */ + /// + typedef T value_type; + + /** @name --- Constructors --- */ + /// + SVector(); + /// + template <class A> + SVector(const Expr<A,T,D>& rhs); + /// + SVector(const SVector<T,D>& rhs); + /// $D1\le D$ required! + template <unsigned int D1> + SVector(const SVector<T,D1>& rhs); + /// $D1\le D-1$ required! + template <unsigned int D1> + SVector(const T& a1, const SVector<T,D1>& rhs); + /// fill from array, len must be equal to D! + SVector(const T* a, unsigned int len); + /// + SVector(const T& rhs); + /// + SVector(const T& a1, const T& a2); + /// + SVector(const T& a1, const T& a2, const T& a3); + /// + SVector(const T& a1, const T& a2, const T& a3, const T& a4); + /// + SVector(const T& a1, const T& a2, const T& a3, const T& a4, + const T& a5); + /// + SVector(const T& a1, const T& a2, const T& a3, const T& a4, + const T& a5, const T& a6); + /// + SVector(const T& a1, const T& a2, const T& a3, const T& a4, + const T& a5, const T& a6, const T& a7); + /// + SVector(const T& a1, const T& a2, const T& a3, const T& a4, + const T& a5, const T& a6, const T& a7, const T& a8); + /// + SVector(const T& a1, const T& a2, const T& a3, const T& a4, + const T& a5, const T& a6, const T& a7, const T& a8, + const T& a9); + /// + SVector(const T& a1, const T& a2, const T& a3, const T& a4, + const T& a5, const T& a6, const T& a7, const T& a8, + const T& a9, const T& a10); + + /// + SVector<T,D>& operator=(const T& rhs); + /// + template <class A> + SVector<T,D>& operator=(const Expr<A,T,D>& rhs); + + /** @name --- Access functions --- */ + /// return dimension $D$ + inline static unsigned int Dim() { return D; } + /// access the parse tree + T apply(unsigned int i) const; + /// return read-only pointer to internal array + const T* Array() const; + /// return pointer to internal array + T* Array(); + + /** @name --- Operators --- */ + /// element wise comparison + bool operator==(const T& rhs) const; + /// element wise comparison + bool operator!=(const T& rhs) const; + /// element wise comparison + bool operator==(const SVector<T,D>& rhs) const; + /// element wise comparison + bool operator!=(const SVector<T,D>& rhs) const; + /// element wise comparison + template <class A> + bool operator==(const Expr<A,T,D>& rhs) const; + /// element wise comparison + template <class A> + bool operator!=(const Expr<A,T,D>& rhs) const; + + /// element wise comparison + bool operator>(const T& rhs) const; + /// element wise comparison + bool operator<(const T& rhs) const; + /// element wise comparison + bool operator>(const SVector<T,D>& rhs) const; + /// element wise comparison + bool operator<(const SVector<T,D>& rhs) const; + /// element wise comparison + template <class A> + bool operator>(const Expr<A,T,D>& rhs) const; + /// element wise comparison + template <class A> + bool operator<(const Expr<A,T,D>& rhs) const; + + /// read-only access + const T& operator[](unsigned int i) const; + /// read-only access + const T& operator()(unsigned int i) const; + /// read/write access + T& operator[](unsigned int i); + /// read/write access + T& operator()(unsigned int i); + + /// + SVector<T,D>& operator+=(const SVector<T,D>& rhs); + /// + SVector<T,D>& operator-=(const SVector<T,D>& rhs); + /// + SVector<T,D>& operator*=(const SVector<T,D>& rhs); + /// + SVector<T,D>& operator/=(const SVector<T,D>& rhs); + + +#ifndef __CINT__ + /// + template <class A> + SVector<T,D>& operator+=(const Expr<A,T,D>& rhs); + /// + template <class A> + SVector<T,D>& operator-=(const Expr<A,T,D>& rhs); + /// + template <class A> + SVector<T,D>& operator*=(const Expr<A,T,D>& rhs); + /// + template <class A> + SVector<T,D>& operator/=(const Expr<A,T,D>& rhs); + +#endif + + /** @name --- Expert functions --- */ + /// transform vector into a vector of lenght 1 + SVector<T,D>& Unit(); + /// place a sub-vector starting at <row> + template <unsigned int D2> + SVector<T,D>& Place_at(const SVector<T,D2>& rhs, const unsigned int row); + /// place a sub-vector starting at <row> + template <class A, unsigned int D2> + SVector<T,D>& Place_at(const Expr<A,T,D2>& rhs, const unsigned int row); + /// used by operator<<() + std::ostream& Print(std::ostream& os) const; + +private: + T fArray[D]; +}; // end of class SVector + + +//============================================================================== +// operator<< +//============================================================================== +template <class T, unsigned int D> +std::ostream& operator<<(std::ostream& os, const ROOT::Math::SVector<T,D>& rhs); + + + + } // namespace Math + +} // namespace ROOT + + + +#ifndef __CINT__ + +// include implementation file +#include "Math/SVector.icc" + +// include operators and functions +#include "Math/UnaryOperators.h" +#include "Math/BinaryOperators.h" +#include "Math/Functions.h" + +#endif // __CINT__ + + +#endif /* ROOT_Math_SVector */ diff --git a/smatrix/inc/Math/SVector.icc b/smatrix/inc/Math/SVector.icc new file mode 100644 index 0000000000000000000000000000000000000000..ed07b07af7eec70c5183af2fbb62cdc3c121526c --- /dev/null +++ b/smatrix/inc/Math/SVector.icc @@ -0,0 +1,465 @@ +// @(#)root/smatrix:$Name: $:$Id: SVector.iccv 1.0 2005/11/24 12:00:00 moneta Exp $ +// Authors: T. Glebe, L. Moneta 2005 + +#ifndef ROOT_Math_SVector_icc +#define ROOT_Math_SVector_icc +// ******************************************************************** +// +// source: +// +// type: source code +// +// created: 21. Mar 2001 +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +// Description: A fixed size Vector class +// +// changes: +// 21 Mar 2001 (TG) creation +// 26 Mar 2001 (TG) added place_at() +// 06 Apr 2001 (TG) CTORS added +// 07 Apr 2001 (TG) CTORS added +// 22 Aug 2001 (TG) CTOR(T*,len) added +// 14 Jan 2002 (TG) added operator==(), operator!=(), operator>(), operator<() +// +// ******************************************************************** +#include <iostream> +#include <assert.h> + + +namespace ROOT { + + namespace Math { + + +//============================================================================== +// Constructors +//============================================================================== +template <class T, unsigned int D> +SVector<T,D>::SVector() { + operator=(0); +} + +template <class T, unsigned int D> +template <class A> +SVector<T,D>::SVector(const Expr<A,T,D>& rhs) { + operator=(rhs); +} + +template <class T, unsigned int D> +SVector<T,D>::SVector(const SVector<T,D>& rhs) { + for(unsigned int i=0; i<D; ++i) + fArray[i] = rhs.fArray[i]; +} + +template <class T, unsigned int D> +template <unsigned int D1> +SVector<T,D>::SVector(const SVector<T,D1>& rhs) { + for(unsigned int i=0; i<D1; ++i) + fArray[i] = rhs.fArray[i]; +} + +template <class T, unsigned int D> +template <unsigned int D1> +SVector<T,D>::SVector(const T& a1, const SVector<T,D1>& rhs) { + fArray[0] = a1; + for(unsigned int i=0; i<D1; ++i) + fArray[i+1] = rhs[i]; +} + +template <class T, unsigned int D> +SVector<T,D>::SVector(const T* a, unsigned int len) { + assert(len == D); + for(unsigned int i=0; i<D; ++i) + fArray[i] = a[i]; +} + +template <class T, unsigned int D> +SVector<T,D>::SVector(const T& rhs) { + for(unsigned int i=0; i<D; ++i) + fArray[i] = rhs; +} + +template <class T, unsigned int D> +SVector<T,D>::SVector(const T& a1, const T& a2) { + fArray[0] = a1; fArray[1] = a2; +} + +template <class T, unsigned int D> +SVector<T,D>::SVector(const T& a1, const T& a2, const T& a3) { + fArray[0] = a1; fArray[1] = a2; fArray[2] = a3; +} + +template <class T, unsigned int D> +SVector<T,D>::SVector(const T& a1, const T& a2, const T& a3, const T& a4) { + fArray[0] = a1; fArray[1] = a2; fArray[2] = a3; fArray[3] = a4; +} + +template <class T, unsigned int D> +SVector<T,D>::SVector(const T& a1, const T& a2, const T& a3, const T& a4, + const T& a5) { + fArray[0] = a1; fArray[1] = a2; fArray[2] = a3; fArray[3] = a4; + fArray[4] = a5; +} + +template <class T, unsigned int D> +SVector<T,D>::SVector(const T& a1, const T& a2, const T& a3, const T& a4, + const T& a5, const T& a6) { + fArray[0] = a1; fArray[1] = a2; fArray[2] = a3; fArray[3] = a4; + fArray[4] = a5; fArray[5] = a6; +} + +template <class T, unsigned int D> +SVector<T,D>::SVector(const T& a1, const T& a2, const T& a3, const T& a4, + const T& a5, const T& a6, const T& a7) { + fArray[0] = a1; fArray[1] = a2; fArray[2] = a3; fArray[3] = a4; + fArray[4] = a5; fArray[5] = a6; fArray[6] = a7; +} + +template <class T, unsigned int D> +SVector<T,D>::SVector(const T& a1, const T& a2, const T& a3, const T& a4, + const T& a5, const T& a6, const T& a7, const T& a8) { + fArray[0] = a1; fArray[1] = a2; fArray[2] = a3; fArray[3] = a4; + fArray[4] = a5; fArray[5] = a6; fArray[6] = a7; fArray[7] = a8; +} + +template <class T, unsigned int D> +SVector<T,D>::SVector(const T& a1, const T& a2, const T& a3, const T& a4, + const T& a5, const T& a6, const T& a7, const T& a8, + const T& a9) { + fArray[0] = a1; fArray[1] = a2; fArray[2] = a3; fArray[3] = a4; + fArray[4] = a5; fArray[5] = a6; fArray[6] = a7; fArray[7] = a8; + fArray[8] = a9; +} + +template <class T, unsigned int D> +SVector<T,D>::SVector(const T& a1, const T& a2, const T& a3, const T& a4, + const T& a5, const T& a6, const T& a7, const T& a8, + const T& a9, const T& a10) { + fArray[0] = a1; fArray[1] = a2; fArray[2] = a3; fArray[3] = a4; + fArray[4] = a5; fArray[5] = a6; fArray[6] = a7; fArray[7] = a8; + fArray[8] = a9; fArray[9] = a10; +} + +//============================================================================== +// operator= +//============================================================================== +template <class T, unsigned int D> +SVector<T,D>& SVector<T,D>::operator=(const T& rhs) { + for(unsigned int i=0; i<D; ++i) { + fArray[i] = rhs; + } + return *this; +} + +template <class T, unsigned int D> +template <class A> +SVector<T,D>& SVector<T,D>::operator=(const Expr<A,T,D>& rhs) { + for(unsigned int i=0; i<D; ++i) { + fArray[i] = rhs.apply(i); + } + return *this; +} + +//============================================================================== +// operator== +//============================================================================== +template <class T, unsigned int D> +bool SVector<T,D>::operator==(const T& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D; ++i) { + rc = rc && (fArray[i] == rhs); + } + return rc; +} + +template <class T, unsigned int D> +bool SVector<T,D>::operator==(const SVector<T,D>& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D; ++i) { + rc = rc && (fArray[i] == rhs.apply(i)); + } + return rc; +} + +template <class T, unsigned int D> +template <class A> +bool SVector<T,D>::operator==(const Expr<A,T,D>& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D; ++i) { + rc = rc && (fArray[i] == rhs.apply(i)); + } + return rc; +} + +//============================================================================== +// operator!= +//============================================================================== +template <class T, unsigned int D> +inline bool SVector<T,D>::operator!=(const T& rhs) const { + return !operator==(rhs); +} + +template <class T, unsigned int D> +inline bool SVector<T,D>::operator!=(const SVector<T,D>& rhs) const { + return !operator==(rhs); +} + +template <class T, unsigned int D> +template <class A> +inline bool SVector<T,D>::operator!=(const Expr<A,T,D>& rhs) const { + return !operator==(rhs); +} + +//============================================================================== +// operator> +//============================================================================== +template <class T, unsigned int D> +bool SVector<T,D>::operator>(const T& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D; ++i) { + rc = rc && (fArray[i] > rhs); + } + return rc; +} + +template <class T, unsigned int D> +bool SVector<T,D>::operator>(const SVector<T,D>& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D; ++i) { + rc = rc && (fArray[i] > rhs.apply(i)); + } + return rc; +} + +template <class T, unsigned int D> +template <class A> +bool SVector<T,D>::operator>(const Expr<A,T,D>& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D; ++i) { + rc = rc && (fArray[i] > rhs.apply(i)); + } + return rc; +} + +//============================================================================== +// operator< +//============================================================================== +template <class T, unsigned int D> +bool SVector<T,D>::operator<(const T& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D; ++i) { + rc = rc && (fArray[i] < rhs); + } + return rc; +} + +template <class T, unsigned int D> +bool SVector<T,D>::operator<(const SVector<T,D>& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D; ++i) { + rc = rc && (fArray[i] < rhs.apply(i)); + } + return rc; +} + +template <class T, unsigned int D> +template <class A> +bool SVector<T,D>::operator<(const Expr<A,T,D>& rhs) const { + bool rc = true; + for(unsigned int i=0; i<D; ++i) { + rc = rc && (fArray[i] < rhs.apply(i)); + } + return rc; +} + +//============================================================================== +// operator+= +//============================================================================== +template <class T, unsigned int D> +SVector<T,D>& SVector<T,D>::operator+=(const SVector<T,D>& rhs) { + for(unsigned int i=0; i<D; ++i) { + fArray[i] += rhs.apply(i); + } + return *this; +} + +template <class T, unsigned int D> +template <class A> +SVector<T,D>& SVector<T,D>::operator+=(const Expr<A,T,D>& rhs) { + for(unsigned int i=0; i<D; ++i) { + fArray[i] += rhs.apply(i); + } + return *this; +} + +//============================================================================== +// operator-= +//============================================================================== +template <class T, unsigned int D> +SVector<T,D>& SVector<T,D>::operator-=(const SVector<T,D>& rhs) { + for(unsigned int i=0; i<D; ++i) { + fArray[i] -= rhs.apply(i); + } + return *this; +} + +template <class T, unsigned int D> +template <class A> +SVector<T,D>& SVector<T,D>::operator-=(const Expr<A,T,D>& rhs) { + for(unsigned int i=0; i<D; ++i) { + fArray[i] -= rhs.apply(i); + } + return *this; +} + +//============================================================================== +// operator*= +//============================================================================== +template <class T, unsigned int D> +SVector<T,D>& SVector<T,D>::operator*=(const SVector<T,D>& rhs) { + for(unsigned int i=0; i<D; ++i) { + fArray[i] *= rhs.apply(i); + } + return *this; +} + +template <class T, unsigned int D> +template <class A> +SVector<T,D>& SVector<T,D>::operator*=(const Expr<A,T,D>& rhs) { + for(unsigned int i=0; i<D; ++i) { + fArray[i] *= rhs.apply(i); + } + return *this; +} + +//============================================================================== +// operator/= +//============================================================================== +template <class T, unsigned int D> +SVector<T,D>& SVector<T,D>::operator/=(const SVector<T,D>& rhs) { + for(unsigned int i=0; i<D; ++i) { + fArray[i] /= rhs.apply(i); + } + return *this; +} + +template <class T, unsigned int D> +template <class A> +SVector<T,D>& SVector<T,D>::operator/=(const Expr<A,T,D>& rhs) { + for(unsigned int i=0; i<D; ++i) { + fArray[i] /= rhs.apply(i); + } + return *this; +} + + +//============================================================================== +// unit +//============================================================================== +template <class T, unsigned int D> +SVector<T,D>& SVector<T,D>::Unit() { + const double len = Mag(*this); + for(unsigned int i=0; i<D; ++i) { + fArray[i] /= len; + } + return *this; +} + +//============================================================================== +// place_at +//============================================================================== +template <class T, unsigned int D> +template <unsigned int D2> +SVector<T,D>& SVector<T,D>::Place_at(const SVector<T,D2>& rhs, const unsigned int row) { + + assert(row+D2 <= D); + // Sassert(end <= D); + + for(unsigned int i=row, j=0; j<D2; ++i,++j) + fArray[i] = rhs.apply(j); + + return *this; +} + + +//============================================================================== +// place_at +//============================================================================== +template <class T, unsigned int D> +template <class A, unsigned int D2> +SVector<T,D>& SVector<T,D>::Place_at(const Expr<A,T,D2>& rhs, const unsigned int row) { + + assert(row+D2 <= D); + + for(unsigned int i=row, j=0; j<D2; ++i,++j) + fArray[i] = rhs.apply(j); + + return *this; +} + +//============================================================================== +// print +//============================================================================== +template <class T, unsigned int D> +std::ostream& SVector<T,D>::Print(std::ostream& os) const { + os.setf(std::ios::right,std::ios::adjustfield); + // os.setf(ios::fixed); + + unsigned int i=0; + for(; i<D-1; ++i) + os << fArray[i] << ", "; + os << fArray[i]; + return os; +} + +//============================================================================== +// Access functions +//============================================================================== +template <class T, unsigned int D> +inline T SVector<T,D>::apply(unsigned int i) const { return fArray[i]; } + +template <class T, unsigned int D> +inline const T* SVector<T,D>::Array() const { return fArray; } + +template <class T, unsigned int D> +inline T* SVector<T,D>::Array() { return fArray; } + +//============================================================================== +// Operators +//============================================================================== +template <class T, unsigned int D> +inline const T& SVector<T,D>::operator[](unsigned int i) const { return fArray[i]; } + +template <class T, unsigned int D> +inline const T& SVector<T,D>::operator()(unsigned int i) const { return fArray[i]; } + +template <class T, unsigned int D> +inline T& SVector<T,D>::operator[](unsigned int i) { return fArray[i]; } + +template <class T, unsigned int D> +inline T& SVector<T,D>::operator()(unsigned int i) { return fArray[i]; } + +//============================================================================== +// operator<< +//============================================================================== +template <class T, unsigned int D> +inline std::ostream& operator<<(std::ostream& os, const SVector<T,D>& rhs) { + return rhs.Print(os); +} + + + + } // namespace Math + +} // namespace ROOT + + +#endif diff --git a/smatrix/inc/Math/UnaryOperators.h b/smatrix/inc/Math/UnaryOperators.h new file mode 100644 index 0000000000000000000000000000000000000000..afc0c9efee90bd5dd30558a36649e6c425bb8474 --- /dev/null +++ b/smatrix/inc/Math/UnaryOperators.h @@ -0,0 +1,271 @@ +// @(#)root/smatrix:$Name: $:$Id: UnaryOperators.hv 1.0 2005/11/24 12:00:00 moneta Exp $ +// Authors: T. Glebe, L. Moneta 2005 + +#ifndef ROOT_Math_UnaryOperators +#define ROOT_Math_UnaryOperators +//====================================================== +// +// ATTENTION: This file was automatically generated, +// do not edit! +// +// author: Thorsten Glebe +// HERA-B Collaboration +// Max-Planck-Institut fuer Kernphysik +// Saupfercheckweg 1 +// 69117 Heidelberg +// Germany +// E-mail: T.Glebe@mpi-hd.mpg.de +// +//====================================================== + +#include <cmath> + +namespace ROOT { + + namespace Math { + + + +template <class T, unsigned int D> class SVector; +template <class T, unsigned int D1, unsigned int D2> class SMatrix; + + +//============================================================================== +// Minus +//============================================================================== +template <class T> +class Minus { +public: + static inline T apply(const T& rhs) { + return -(rhs); + } +}; + +//============================================================================== +// operator- (Expr, unary) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<UnaryOp<Minus<T>, Expr<A,T,D>, T>, T, D> + operator-(const Expr<A,T,D>& rhs) { + typedef UnaryOp<Minus<T>, Expr<A,T,D>, T> MinusUnaryOp; + + return Expr<MinusUnaryOp,T,D>(MinusUnaryOp(Minus<T>(),rhs)); +} + + +//============================================================================== +// operator- (SVector, unary) +//============================================================================== +template <class T, unsigned int D> +inline Expr<UnaryOp<Minus<T>, SVector<T,D>, T>, T, D> + operator-(const SVector<T,D>& rhs) { + typedef UnaryOp<Minus<T>, SVector<T,D>, T> MinusUnaryOp; + + return Expr<MinusUnaryOp,T,D>(MinusUnaryOp(Minus<T>(),rhs)); +} + +//============================================================================== +// operator- (MatrixExpr, unary) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<UnaryOp<Minus<T>, Expr<A,T,D,D2>, T>, T, D, D2> + operator-(const Expr<A,T,D,D2>& rhs) { + typedef UnaryOp<Minus<T>, Expr<A,T,D,D2>, T> MinusUnaryOp; + + return Expr<MinusUnaryOp,T,D,D2>(MinusUnaryOp(Minus<T>(),rhs)); +} + + +//============================================================================== +// operator- (SMatrix, unary) +//============================================================================== +template <class T, unsigned int D, unsigned int D2> +inline Expr<UnaryOp<Minus<T>, SMatrix<T,D,D2>, T>, T, D, D2> + operator-(const SMatrix<T,D,D2>& rhs) { + typedef UnaryOp<Minus<T>, SMatrix<T,D,D2>, T> MinusUnaryOp; + + return Expr<MinusUnaryOp,T,D,D2>(MinusUnaryOp(Minus<T>(),rhs)); +} + + +//============================================================================== +// Fabs +//============================================================================== +template <class T> +class Fabs { +public: + static inline T apply(const T& rhs) { + return std::fabs(rhs); + } +}; + +//============================================================================== +// fabs (Expr, unary) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<UnaryOp<Fabs<T>, Expr<A,T,D>, T>, T, D> + fabs(const Expr<A,T,D>& rhs) { + typedef UnaryOp<Fabs<T>, Expr<A,T,D>, T> FabsUnaryOp; + + return Expr<FabsUnaryOp,T,D>(FabsUnaryOp(Fabs<T>(),rhs)); +} + + +//============================================================================== +// fabs (SVector, unary) +//============================================================================== +template <class T, unsigned int D> +inline Expr<UnaryOp<Fabs<T>, SVector<T,D>, T>, T, D> + fabs(const SVector<T,D>& rhs) { + typedef UnaryOp<Fabs<T>, SVector<T,D>, T> FabsUnaryOp; + + return Expr<FabsUnaryOp,T,D>(FabsUnaryOp(Fabs<T>(),rhs)); +} + +//============================================================================== +// fabs (MatrixExpr, unary) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<UnaryOp<Fabs<T>, Expr<A,T,D,D2>, T>, T, D, D2> + fabs(const Expr<A,T,D,D2>& rhs) { + typedef UnaryOp<Fabs<T>, Expr<A,T,D,D2>, T> FabsUnaryOp; + + return Expr<FabsUnaryOp,T,D,D2>(FabsUnaryOp(Fabs<T>(),rhs)); +} + + +//============================================================================== +// fabs (SMatrix, unary) +//============================================================================== +template <class T, unsigned int D, unsigned int D2> +inline Expr<UnaryOp<Fabs<T>, SMatrix<T,D,D2>, T>, T, D, D2> + fabs(const SMatrix<T,D,D2>& rhs) { + typedef UnaryOp<Fabs<T>, SMatrix<T,D,D2>, T> FabsUnaryOp; + + return Expr<FabsUnaryOp,T,D,D2>(FabsUnaryOp(Fabs<T>(),rhs)); +} + + +//============================================================================== +// Sqr +//============================================================================== +template <class T> +class Sqr { +public: + static inline T apply(const T& rhs) { + return square(rhs); + } +}; + +//============================================================================== +// sqr (Expr, unary) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<UnaryOp<Sqr<T>, Expr<A,T,D>, T>, T, D> + sqr(const Expr<A,T,D>& rhs) { + typedef UnaryOp<Sqr<T>, Expr<A,T,D>, T> SqrUnaryOp; + + return Expr<SqrUnaryOp,T,D>(SqrUnaryOp(Sqr<T>(),rhs)); +} + + +//============================================================================== +// sqr (SVector, unary) +//============================================================================== +template <class T, unsigned int D> +inline Expr<UnaryOp<Sqr<T>, SVector<T,D>, T>, T, D> + sqr(const SVector<T,D>& rhs) { + typedef UnaryOp<Sqr<T>, SVector<T,D>, T> SqrUnaryOp; + + return Expr<SqrUnaryOp,T,D>(SqrUnaryOp(Sqr<T>(),rhs)); +} + +//============================================================================== +// sqr (MatrixExpr, unary) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<UnaryOp<Sqr<T>, Expr<A,T,D,D2>, T>, T, D, D2> + sqr(const Expr<A,T,D,D2>& rhs) { + typedef UnaryOp<Sqr<T>, Expr<A,T,D,D2>, T> SqrUnaryOp; + + return Expr<SqrUnaryOp,T,D,D2>(SqrUnaryOp(Sqr<T>(),rhs)); +} + + +//============================================================================== +// sqr (SMatrix, unary) +//============================================================================== +template <class T, unsigned int D, unsigned int D2> +inline Expr<UnaryOp<Sqr<T>, SMatrix<T,D,D2>, T>, T, D, D2> + sqr(const SMatrix<T,D,D2>& rhs) { + typedef UnaryOp<Sqr<T>, SMatrix<T,D,D2>, T> SqrUnaryOp; + + return Expr<SqrUnaryOp,T,D,D2>(SqrUnaryOp(Sqr<T>(),rhs)); +} + + +//============================================================================== +// Sqrt +//============================================================================== +template <class T> +class Sqrt { +public: + static inline T apply(const T& rhs) { + return std::sqrt(rhs); + } +}; + +//============================================================================== +// sqrt (Expr, unary) +//============================================================================== +template <class A, class T, unsigned int D> +inline Expr<UnaryOp<Sqrt<T>, Expr<A,T,D>, T>, T, D> + sqrt(const Expr<A,T,D>& rhs) { + typedef UnaryOp<Sqrt<T>, Expr<A,T,D>, T> SqrtUnaryOp; + + return Expr<SqrtUnaryOp,T,D>(SqrtUnaryOp(Sqrt<T>(),rhs)); +} + + +//============================================================================== +// sqrt (SVector, unary) +//============================================================================== +template <class T, unsigned int D> +inline Expr<UnaryOp<Sqrt<T>, SVector<T,D>, T>, T, D> + sqrt(const SVector<T,D>& rhs) { + typedef UnaryOp<Sqrt<T>, SVector<T,D>, T> SqrtUnaryOp; + + return Expr<SqrtUnaryOp,T,D>(SqrtUnaryOp(Sqrt<T>(),rhs)); +} + +//============================================================================== +// sqrt (MatrixExpr, unary) +//============================================================================== +template <class A, class T, unsigned int D, unsigned int D2> +inline Expr<UnaryOp<Sqrt<T>, Expr<A,T,D,D2>, T>, T, D, D2> + sqrt(const Expr<A,T,D,D2>& rhs) { + typedef UnaryOp<Sqrt<T>, Expr<A,T,D,D2>, T> SqrtUnaryOp; + + return Expr<SqrtUnaryOp,T,D,D2>(SqrtUnaryOp(Sqrt<T>(),rhs)); +} + + +//============================================================================== +// sqrt (SMatrix, unary) +//============================================================================== +template <class T, unsigned int D, unsigned int D2> +inline Expr<UnaryOp<Sqrt<T>, SMatrix<T,D,D2>, T>, T, D, D2> + sqrt(const SMatrix<T,D,D2>& rhs) { + typedef UnaryOp<Sqrt<T>, SMatrix<T,D,D2>, T> SqrtUnaryOp; + + return Expr<SqrtUnaryOp,T,D,D2>(SqrtUnaryOp(Sqrt<T>(),rhs)); +} + + + } // namespace Math + +} // namespace ROOT + + + +#endif /* ROOT_Math_UnaryOperators */ diff --git a/smatrix/src/Dict.h b/smatrix/src/Dict.h new file mode 100644 index 0000000000000000000000000000000000000000..ffb4ff9a2da680c5b0943cdc89dda0fb7fe71afe --- /dev/null +++ b/smatrix/src/Dict.h @@ -0,0 +1,5 @@ +#include "SMatrix.hh" +#include "SVector.hh" + +SMatrix<double,2,2> m; +SVector<double,2> v; diff --git a/smatrix/src/Selection.xml b/smatrix/src/Selection.xml new file mode 100644 index 0000000000000000000000000000000000000000..411f2a0c39ec64c58f6eed1fc8a5219286634486 --- /dev/null +++ b/smatrix/src/Selection.xml @@ -0,0 +1,4 @@ +<lcgdict> + <class pattern ="SMatrix<double,*"/> + <class pattern ="SVector<double,*"/> +</lcgdict> \ No newline at end of file diff --git a/smatrix/test/TestTimer.h b/smatrix/test/TestTimer.h new file mode 100644 index 0000000000000000000000000000000000000000..312cbad43d361cd0b1a028c7994b2ae267f6f8db --- /dev/null +++ b/smatrix/test/TestTimer.h @@ -0,0 +1,52 @@ +// simple class to measure time + +#include "TStopwatch.h" + + + +namespace ROOT { + + namespace Math{ + + namespace test { + + + void printTime(TStopwatch & time, std::string s) { + int pr = std::cout.precision(8); + std::cout << s << "\t" << " time = " << time.RealTime() << "\t(sec)\t" + // << time.CpuTime() + << std::endl; + std::cout.precision(pr); + } + + class Timer { + + public: + + Timer(const std::string & s = "") : fName(s), fTime(0) + { + fWatch.Start(); + } + Timer(double & t, const std::string & s = "") : fName(s), fTime(&t) + { + fWatch.Start(); + } + + ~Timer() { + fWatch.Stop(); + printTime(fWatch,fName); + if (fTime) *fTime += fWatch.RealTime(); + } + + + private: + + std::string fName; + double * fTime; + TStopwatch fWatch; + + }; + } + + } +} diff --git a/smatrix/test/matrix_op.h b/smatrix/test/matrix_op.h new file mode 100644 index 0000000000000000000000000000000000000000..2548045592cfaf3b3333e3f18828a3b5027b9bf5 --- /dev/null +++ b/smatrix/test/matrix_op.h @@ -0,0 +1,103 @@ +#include "TestTimer.h" + +// define funcitons for matrix operations + +//#define DEBUG +#ifndef NLOOP +#define NLOOP 1000000 +#endif + + +// vector assignment +template<class V> +void testVeq(const V & v, double & time, V & result) { + test::Timer t(time,"V=V "); + for (int l = 0; l < NLOOP; l++) + { + result = v; + } +} + +// matrix assignmnent +template<class M> +void testMeq(const M & m, double & time, M & result) { + test::Timer t(time,"M=M "); + for (int l = 0; l < NLOOP; l++) + { + result = m; + } +} + + + +// vector sum +template<class V> +void testVad(const V & v1, const V & v2, double & time, V & result) { + test::Timer t(time,"V+V ");; + for (int l = 0; l < NLOOP; l++) + { + result = v1 + v2; + } +} + +// matrix sum +template<class M> +void testMad(const M & m1, const M & m2, double & time, M & result) { + test::Timer t(time,"M+M ");; + for (int l = 0; l < NLOOP; l++) + { + result = m1 + m2; + } +} + +// vector * constant +template<class V> +void testVscale(const V & v1, double a, double & time, V & result) { + test::Timer t(time,"a*V ");; + for (int l = 0; l < NLOOP; l++) + { + result = a * v1; // v1 * a does not exist in ROOT + } +} + + +// matrix * constant +template<class M> +void testMscale(const M & m1, double a, double & time, M & result) { + test::Timer t(time,"a*M ");; + for (int l = 0; l < NLOOP; l++) + { + result = m1 * a; + } +} + + +// simple Matrix vector op +template<class M, class V> +void testMV(const M & mat, const V & v, double & time, V & result) { + test::Timer t(time,"M*V "); + for (int l = 0; l < NLOOP; l++) + { + result = mat * v; + } +} + +// general matrix vector op +template<class M, class V> +void testGMV(const M & mat, const V & v1, const V & v2, double & time, V & result) { + test::Timer t(time,"M*V+"); + for (int l = 0; l < NLOOP; l++) + { + result = mat * v1 + v2; + } +} + +// general matrix matrix op +template<class A, class B, class C> +void testMM(const A & a, const B & b, const C & c, double & time, C & result) { + test::Timer t(time,"M*M "); + for (int l = 0; l < NLOOP; l++) + { + result = a * b + c; + } +} diff --git a/smatrix/test/testIO.C b/smatrix/test/testIO.C new file mode 100644 index 0000000000000000000000000000000000000000..9cda39e44977d3bab80dd63991b3b8c75c81b871 --- /dev/null +++ b/smatrix/test/testIO.C @@ -0,0 +1,36 @@ +{ +gSystem->Load("libSmatrix"); +using namespace ROOT::Math; +SMatrix<double,2,2> m; +//cout << m << endl; + +double * d = m.Array(); +d[1] = 1; +d[2] = 2; +d[3] = 3; +//m.Print(); +m.print(cout); + +TFile f("testSmatrix.root","RECREATE"); + +f.WriteObjectAny(&m,"SMatrix<double,2,2>","m"); + +f.Close(); + +cout << "\nReading File..\n\n"; + +TFile f2("testSmatrix.root"); + +SMatrix<double,2,2> * p_m2 = (SMatrix<double,2,2> *) f2.GetObjectUnchecked("m"); +SMatrix<double,2,2> m2 = *p_m2; +m2.print(cout); +cout << endl; + +cout << " Test read matrix = original matrix "; +if ( m2 == m ) + cout << " OK " << endl; +else +cout << " Failed " << endl; + +f2.Close(); +} diff --git a/smatrix/test/testKalman.cxx b/smatrix/test/testKalman.cxx new file mode 100644 index 0000000000000000000000000000000000000000..9c0bcee215a753c38a078d77595dc859676e329a --- /dev/null +++ b/smatrix/test/testKalman.cxx @@ -0,0 +1,283 @@ + + +#include "Math/SVector.h" +#include "Math/SMatrix.h" + +#include "TMatrixD.h" +#include "TVectorD.h" + +#include "TRandom3.h" + +// #include "SealUtil/SealTimer.h" +// #include "SealUtil/SealHRRTChrono.h" +// #include "SealUtil/TimingReport.h" + +#include <iostream> + +#ifndef NDIM1 +#define NDIM1 2 +#endif +#ifndef NDIM2 +#define NDIM2 5 +#endif + +#define NITER 1 // number of iterations + +#define NLOOP 1000000 // number of time the test is repeted + +using namespace ROOT::Math; + +#include "TestTimer.h" + +int test_smatrix_kalman() { + + // need to write explicitly the dimensions + + + typedef SMatrix<double, NDIM1, NDIM1> MnMatrixNN; + typedef SMatrix<double, NDIM2, NDIM2> MnMatrixMM; + typedef SMatrix<double, NDIM1, NDIM2> MnMatrixNM; + typedef SMatrix<double, NDIM2 , NDIM1> MnMatrixMN; + typedef SMatrix<double, NDIM1 > MnSymMatrixNN; + typedef SMatrix<double, NDIM2 > MnSymMatrixMM; + typedef SVector<double, NDIM1> MnVectorN; + typedef SVector<double, NDIM2> MnVectorM; + + + + int first = NDIM1; //Can change the size of the matrices + int second = NDIM2; + + + std::cout << "************************************************\n"; + std::cout << " SMatrix kalman test " << first << " x " << second << std::endl; + std::cout << "************************************************\n"; + + + + + int npass = NITER; + TRandom3 r(111); + double x2sum = 0; + for (int k = 0; k < npass; k++) { + + + + MnMatrixNM H; + MnMatrixMN K0; + MnSymMatrixMM Cp; + MnSymMatrixNN V; + MnVectorN m; + MnVectorM xp; + + + { + + // fill matrices with ranodm data + for(int i = 0; i < first; i++) + for(int j = 0; j < second; j++) + H(i,j) = r.Rndm() + 1.; + for(int i = 0; i < second; i++) + for(int j = 0; j < first; j++) + K0(i,j) = r.Rndm() + 1.; + // sym matrices + for(int i = 0; i < second; i++) + for(int j = 0; j <=i; j++) { + Cp(i,j) = r.Rndm() + 1.; + if (j != i) Cp(j,i) = Cp(i,j); + } + for(int i = 0; i < first; i++) + for(int j = 0; j <=i; j++) { + V(i,j) = r.Rndm() + 1.; + if (j != i) V(j,i) = V(i,j); + } + // vectors + for(int i = 0; i < first; i++) + m(i) = r.Rndm() + 1.; + for(int i = 0; i < second; i++) + xp(i) = r.Rndm() + 1.; + + } + + + MnSymMatrixMM I; + for(int i = 0; i < second; i++) + I(i,i) = 1; + +#ifdef DEBUG + std::cout << "pass " << k << std::endl; + if (k == 0) { + std::cout << " K0 = " << K0 << std::endl; + std::cout << " H = " << K0 << std::endl; + std::cout << " Cp = " << Cp << std::endl; + std::cout << " V = " << V << std::endl; + std::cout << " m = " << m << std::endl; + std::cout << " xp = " << xp << std::endl; + } +#endif + + + { + double x2 = 0; + test::Timer t("SMatrix Kalman "); + + MnVectorM x; + MnMatrixMN tmp; + MnSymMatrixNN Rinv; + MnMatrixMN K; + MnSymMatrixMM C; + MnVectorN vtmp; + + for (int l = 0; l < NLOOP; l++) + { + + + + + x = xp + K0 * (m- H * xp); + tmp = Cp * transpose(H); + Rinv = V + H * tmp; + + bool test = Rinv.Invert(); + if(!test) { + std::cout<<"inversion failed" <<std::endl; + std::cout << Rinv << std::endl; + } + + K = tmp * Rinv; + C = ( I - K * H ) * Cp; + //x2 = product(Rinv,m-H*xp); // this does not compile on WIN32 + vtmp = m-H*xp; + x2 = Dot(vtmp, Rinv*vtmp); + + } + //std::cout << k << " chi2 = " << x2 << std::endl; + x2sum += x2; + } + } + //tr.dump(); + + std::cout << "x2sum = " << x2sum << std::endl; + + return 0; +} + +// ROOT test + + +int test_tmatrix_kalman() { + + + + + typedef TMatrixD MnMatrix; + typedef TVectorD MnVector; + +// typedef boost::numeric::ublas::matrix<double> MnMatrix; + //typedef HepSymMatrix MnSymMatrixHep; + + + int first = NDIM1; //Can change the size of the matrices + int second = NDIM2; + + + std::cout << "************************************************\n"; + std::cout << " TMatrix Kalman test " << first << " x " << second << std::endl; + std::cout << "************************************************\n"; + + + + int npass = NITER; + TRandom3 r(111); + double x2sum = 0; + + for (int k = 0; k < npass; k++) + { + MnMatrix H(first,second); + for(int i = 0; i < first; i++) + for(int j = 0; j < second; j++) + H(i,j) = r.Rndm() + 1.; + MnMatrix K0(second,first); + for(int i = 0; i < second; i++) + for(int j = 0; j < first; j++) + K0(i,j) = r.Rndm() + 1.; + //MnSymMatrix Cp(second); + MnMatrix Cp(second,second); + //in ROOT a sym matrix is like a normal matrix + for(int i = 0; i < second; i++) + for(int j = 0; j <=i; j++){ + Cp(i,j) = r.Rndm() + 1.; + if (j != i) Cp(j,i) = Cp(i,j); + } + //MnSymMatrix V(first); + MnMatrix V(first,first); + for(int i = 0; i < first; i++) + for(int j = 0; j <=i; j++) { + V(i,j) = r.Rndm() + 1.; + if (j != i) V(j,i) = V(i,j); + } + MnVector m(first); + for(int j = 0; j < first; j++) + m(j) = r.Rndm() + 1.; + MnVector xp(second); + for(int j = 0; j < second; j++) + xp(j) = r.Rndm() + 1.; + //MnSymMatrix I(second);//Identity matrix + MnMatrix I(second,second);//Identity matrix + for (int i = 0; i < second; i++) + for(int j = 0; j <second; j++) { + I(i,j) = 0.0; + if (i==j) I(i,i) = 1.0; + } + +// if (k==0) { +// std::cout << " Cp " << std::endl; +// Cp.Print(); +// } + + { + double x2 = 0; + MnVector x(second); + MnMatrix tmp(second,first); + MnMatrix Rinv(first,first); + MnMatrix K(second,first); + MnMatrix C(second,second); + MnVector vtmp(first); + + test::Timer t("TMatrix Kalman "); + for (int l = 0; l < NLOOP; l++) + { + //MnVector x = xp + K0*(m-H*xp); + x = xp + K0*(m-H*xp); + MnMatrix HT = H; + //MnMatrix tmp = Cp*HT.Transpose(HT); + tmp = Cp*HT.Transpose(HT); + double det; + //MnMatrix Rinv =(V + H *tmp).InvertFast(&det); + Rinv =(V + H *tmp).InvertFast(&det); + //MnMatrix K = tmp * Rinv; + //MnMatrix C = (I - K * H) * Cp; + //K = tmp * Rinv; + C = (I - tmp* Rinv * H) * Cp; + vtmp = m-H*xp; + x2 = vtmp * (Rinv * vtmp); + } + //std::cout << k << " chi2 " << x2 << std::endl; + x2sum += x2; + } + // } + } + //tr.dump(); + //print sum of x2 to check that result is same as other tests + std::cout << "x2sum = " << x2sum << std::endl; + + return 0; +} + + + +int main() { + + test_smatrix_kalman(); + test_tmatrix_kalman(); +} diff --git a/smatrix/test/testOperations.cxx b/smatrix/test/testOperations.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8ff381ee27c495ea01eb9ffd946c6806a726338a --- /dev/null +++ b/smatrix/test/testOperations.cxx @@ -0,0 +1,366 @@ + + +#include "Math/SVector.h" +#include "Math/SMatrix.h" + +#include "TMatrixD.h" +#include "TVectorD.h" + +#include "TRandom3.h" + +// #include "SealUtil/SealTimer.h" +// #include "SealUtil/SealHRRTChrono.h" +// #include "SealUtil/TimingReport.h" + +#include <iostream> + +#ifndef NDIM1 +#define NDIM1 5 +#endif +#ifndef NDIM2 +#define NDIM2 5 +#endif + +#define NITER 1 // number of iterations + +using namespace ROOT::Math; + +#include "matrix_op.h" + + + +template<class V> +double testDot_S(const V & v1, const V & v2, double & time) { + test::Timer t(time,"dot "); + double result=0; + for (int l = 0; l < NLOOP; l++) + { + result = Dot(v1,v2); + } + return result; +} + +template<class M, class V> +double testInnerProd_S(const M & a, const V & v, double & time) { + test::Timer t(time,"prod"); + double result=0; + for (int l = 0; l < NLOOP; l++) + { +#ifndef WIN32 + result = Product(v,a); +#else + // cannot instantiate on Windows (don't know why? ) + V tmp = a*v; + result = Dot(v,tmp); +#endif + } + return result; +} + +//inversion +template<class M> +void testInv_S(const M & a, double & time, M& result){ + test::Timer t(time,"inv "); + for (int l = 0; l < NLOOP; l++) + { + result = a; + result.Invert(); + } +} + +// for root + + +template<class V> +double testDot_T(const V & v1, const V & v2, double & time) { + test::Timer t(time,"dot "); + double result=0; + int size = v1.GetNrows(); + assert(size == v2.GetNrows() ); + for (int l = 0; l < NLOOP; l++) + { + result = 0; + for (int i = 0; i < size; ++i) + result += v1(i)*v2(i); + } + return result; +} + +template<class M, class V> +double testInnerProd_T(const M & a, const V & v, double & time) { + test::Timer t(time,"prod"); + double result=0; + int size = v.GetNrows(); + for (int l = 0; l < NLOOP; l++) + { + V tmp = a * v; + //result = v * tmp; + result = 0; + for (int i = 0; i < size; ++i) + result += v(i)*tmp(i); + } + return result; +} + +//inversion +template<class M> +void testInv_T(const M & a, double & time, M& result){ + test::Timer t(time,"inv "); + for (int l = 0; l < NLOOP; l++) + { + result = a; + result.InvertFast(); + } +} + +template<class M> +void testInv_T2(const M & a, double & time, M& result){ + test::Timer t(time,"inv2"); + for (int l = 0; l < NLOOP; l++) + { + result = a; + result.InvertFast(); + } +} + + + +int test_smatrix_op() { + + // need to write explicitly the dimensions + + + typedef SMatrix<double, NDIM1, NDIM1> MnMatrixNN; + typedef SMatrix<double, NDIM2, NDIM2> MnMatrixMM; + typedef SMatrix<double, NDIM1, NDIM2> MnMatrixNM; + typedef SMatrix<double, NDIM2 , NDIM1> MnMatrixMN; + typedef SVector<double, NDIM1> MnVectorN; + typedef SVector<double, NDIM2> MnVectorM; + + + + int first = NDIM1; //Can change the size of the matrices + int second = NDIM2; + + + std::cout << "************************************************\n"; + std::cout << " SMatrix operations test " << first << " x " << second << std::endl; + std::cout << "************************************************\n"; + + +// seal::TimingReport tr; +// seal::TimingItem & init = tr.item<seal::SealHRRTChrono>("init"); + +// seal::TimingItem & t_veq = tr.item<seal::SealHRRTChrono>("smatrix veq"); +// seal::TimingItem & t_meq = tr.item<seal::SealHRRTChrono>("smatrix meq"); +// seal::TimingItem & t_vad = tr.item<seal::SealHRRTChrono>("smatrix vad"); +// seal::TimingItem & t_mad = tr.item<seal::SealHRRTChrono>("smatrix mad"); +// seal::TimingItem & t_dot = tr.item<seal::SealHRRTChrono>("smatrix dot"); +// seal::TimingItem & t_mv = tr.item<seal::SealHRRTChrono>("smatrix MV "); +// seal::TimingItem & t_gmv = tr.item<seal::SealHRRTChrono>("smatrix GMV"); +// seal::TimingItem & t_mm = tr.item<seal::SealHRRTChrono>("smatrix GMM"); +// seal::TimingItem & t_prd = tr.item<seal::SealHRRTChrono>("smatrix prd"); +// seal::TimingItem & t_inv = tr.item<seal::SealHRRTChrono>("smatrix inv"); + + double t_veq, t_meq, t_vad, t_mad, t_dot, t_mv, t_gmv, t_mm, t_prd, t_inv, t_vsc, t_msc = 0; + + + + double r1,r2; + int npass = NITER; + TRandom3 r(111); + for (int k = 0; k < npass; k++) { + + + MnMatrixNM A; + MnMatrixMN B; + MnMatrixNN C; + MnMatrixMM D; + MnVectorN v; + MnVectorM p; + + { + //seal::SealTimer t(init,false); + // fill matrices with ranodm data + for(int i = 0; i < first; i++) + for(int j = 0; j < second; j++) + A(i,j) = r.Rndm() + 1.; + for(int i = 0; i < second; i++) + for(int j = 0; j < first; j++) + B(i,j) = r.Rndm() + 1.; + for(int i = 0; i < first; i++) + for(int j = 0; j < first; j++) + C(i,j) = r.Rndm() + 1.; + for(int i = 0; i < second; i++) + for(int j = 0; j < second; j++) + D(i,j) = r.Rndm() + 1.; + +// // sym matrices +// for(int i = 0; i < second; i++) +// for(int j = 0; j <=i; j++) { +// C(i,j) = r.Rndm() + 1.; +// if (j != i) Cp(j,i) = Cp(i,j); +// } + // vectors + for(int i = 0; i < first; i++) + v(i) = r.Rndm() + 1.; + for(int i = 0; i < second; i++) + p(i) = r.Rndm() + 1.; + + } + + +// MnSymMatrixMM I; +// for(int i = 0; i < second; i++) +// I(i,i) = 1; + +#ifdef DEBUG + std::cout << "pass " << k << std::endl; + if (k == 0) { + std::cout << " A = " << A << std::endl; + std::cout << " B = " << B << std::endl; + std::cout << " C = " << C << std::endl; + std::cout << " D = " << D << std::endl; + std::cout << " v = " << v << std::endl; + std::cout << " p = " << p << std::endl; + } +#endif + + MnVectorN v1; testMV(A,v,t_mv,v1); + MnVectorN v2; testGMV(A,v,v1,t_gmv,v2); + MnMatrixNN C1; testMM(A,B,C,t_mm,C1); + MnMatrixNN C2; testInv_S(C1,t_inv,C2); + MnVectorN v3; testVeq(v,t_veq,v3); + MnVectorN v4; testVad(v2,v3,t_vad,v4); + MnVectorN v5; testVscale(v4,2.0,t_vsc,v5); + MnMatrixNN C3; testMeq(C,t_meq,C3); + MnMatrixNN C4; testMad(C2,C3,t_mad,C4); + MnMatrixNN C5; testMscale(C4,0.5,t_msc,C5); + + r1 = testDot_S(v3,v5,t_dot); + r2 = testInnerProd_S(C5,v5,t_prd); + + } + //tr.dump(); + + std::cout << " r1 = " << r1 << " r2 = " << r2 << std::endl; + + return 0; +} + +// ROOT test + + +int test_tmatrix_op() { + + + + + typedef TMatrixD MnMatrix; + typedef TVectorD MnVector; + +// typedef boost::numeric::ublas::matrix<double> MnMatrix; + //typedef HepSymMatrix MnSymMatrixHep; + + + int first = NDIM1; //Can change the size of the matrices + int second = NDIM2; + + + std::cout << "************************************************\n"; + std::cout << " TMatrix operations test " << first << " x " << second << std::endl; + std::cout << "************************************************\n"; + + double t_veq, t_meq, t_vad, t_mad, t_dot, t_mv, t_gmv, t_mm, t_prd, t_inv, t_inv2, t_vsc, t_msc = 0; + + + double r1,r2; + int npass = NITER; + TRandom3 r(111); + + for (int k = 0; k < npass; k++) { + + + MnMatrix A(NDIM1,NDIM2); + MnMatrix B(NDIM2,NDIM1); + MnMatrix C(NDIM1,NDIM1); + MnMatrix D(NDIM2,NDIM2); + MnVector v(NDIM1); + MnVector p(NDIM2); + + { + // seal::SealTimer t(init,false); + // fill matrices with ranodm data + for(int i = 0; i < first; i++) + for(int j = 0; j < second; j++) + A(i,j) = r.Rndm() + 1.; + for(int i = 0; i < second; i++) + for(int j = 0; j < first; j++) + B(i,j) = r.Rndm() + 1.; + for(int i = 0; i < first; i++) + for(int j = 0; j < first; j++) + C(i,j) = r.Rndm() + 1.; + for(int i = 0; i < second; i++) + for(int j = 0; j < second; j++) + D(i,j) = r.Rndm() + 1.; + +// // sym matrices +// for(int i = 0; i < second; i++) +// for(int j = 0; j <=i; j++) { +// C(i,j) = r.Rndm() + 1.; +// if (j != i) Cp(j,i) = Cp(i,j); +// } + // vectors + for(int i = 0; i < first; i++) + v(i) = r.Rndm() + 1.; + for(int i = 0; i < second; i++) + p(i) = r.Rndm() + 1.; + + } + + +// MnSymMatrixMM I; +// for(int i = 0; i < second; i++) +// I(i,i) = 1; + +#ifdef DEBUG + std::cout << "pass " << k << std::endl; + if (k == 0) { + A.Print(); B.Print(); C.Print(); D.Print(); v.Print(); p.Print(); + } +#endif + + + MnVector v1(NDIM1); testMV(A,v,t_mv,v1); + MnVector v2(NDIM1); testGMV(A,v,v1,t_gmv,v2); + MnMatrix C1(NDIM1,NDIM1); testMM(A,B,C,t_mm,C1); + MnMatrix C2(NDIM1,NDIM1); testInv_T(C1,t_inv,C2); + MnVector v3(NDIM1); testVeq(v,t_veq,v3); + MnVector v4(NDIM1); testVad(v2,v3,t_vad,v4); + MnVector v5(NDIM1); testVscale(v4,2.0,t_vsc,v5); + MnMatrix C3(NDIM1,NDIM1); testMeq(C,t_meq,C3); + MnMatrix C4(NDIM1,NDIM1); testMad(C2,C3,t_mad,C4); + MnMatrix C5(NDIM1,NDIM1); testMscale(C4,0.5,t_msc,C5); + + + r1 = testDot_T(v3,v5,t_dot); + r2 = testInnerProd_T(C5,v5,t_prd); + + MnMatrix C2b(NDIM1,NDIM1); testInv_T2(C1,t_inv2,C2b); + + + } + // tr.dump(); + + std::cout << " r1 = " << r1 << " r2 = " << r2 << std::endl; + + return 0; +} + + + +int main() { + + test_smatrix_op(); + test_tmatrix_op(); +} diff --git a/smatrix/test/testSMatrix.cxx b/smatrix/test/testSMatrix.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f67f987de222a37f33752063fb3d1d4147f51dc3 --- /dev/null +++ b/smatrix/test/testSMatrix.cxx @@ -0,0 +1,235 @@ +#include <cmath> +#include "Math/SVector.h" +#include "Math/SMatrix.h" + +#include <iostream> + +using namespace ROOT::Math; + +using std::cout; +using std::endl; + + +#define XXX + +int test1() { + + SVector<float,3> x(4,5,6); + SVector<float,2> y(2,3); + cout << "x: " << x << endl; + cout << "y: " << y << endl; + + SMatrix<float,4,3> A; + SMatrix<float,2,2> B; + + A.Place_in_row(y, 1, 1); + A.Place_in_col(x + 2, 1, 0); + A.Place_at(B , 2, 1); + cout << "A: " << endl << A << endl; + + return 0; + +} + +int test2() { +#ifdef XXX + SMatrix<double,3> A; + A(0,0) = A(1,0) = 1; + A(0,1) = 3; + A(1,1) = A(2,2) = 2; + cout << "A: " << endl << A << endl; + + SVector<double,3> x = A.Row(0); + cout << "x: " << x << endl; + + SVector<double,3> y = A.Col(1); + cout << "y: " << y << endl; + + return 0; +#endif +} + +int test3() { +#ifdef XXX + SMatrix<double,3> A; + A(0,0) = A(0,1) = A(1,0) = 1; + A(1,1) = A(2,2) = 2; + + SMatrix<double,3> B = A; // save A in B + cout << "A: " << endl << A << endl; + + double det = 0.; + A.Sdet(det); + cout << "Determinant: " << det << endl; + // WARNING: A has changed!! + cout << "A again: " << endl << A << endl; + + A.Sinvert(); + cout << "A^-1: " << endl << A << endl; + + // check if this is really the inverse: + cout << "A^-1 * B: " << endl << A * B << endl; + + return 0; +#endif +} + +int test4() { +#ifdef XXX + SMatrix<double,3> A; + A(0,0) = A(0,1) = A(1,0) = 1; + A(1,1) = A(2,2) = 2; + cout << " A: " << endl << A << endl; + + SVector<double,3> x(1,2,3); + cout << "x: " << x << endl; + + // we add 1 to each component of x and A + cout << " (x+1)^T * (A+1) * (x+1): " << Product(x+1,A+1) << endl; + + return 0; +#endif +} + +int test5() { +#ifdef XXX + SMatrix<float,4,3> A; + A(0,0) = A(0,1) = A(1,1) = A(2,2) = 4.; + A(2,3) = 1.; + cout << "A: " << endl << A << endl; + SVector<float,4> x(1,2,3,4); + cout << " x: " << x << endl; + SVector<float,3> a(1,2,3); + cout << " a: " << a << endl; + SVector<float,4> y = x + A * a; + // SVector<float,4> y = A * a; + cout << " y: " << y << endl; + + SVector<float,3> b = (x+1) * (A+1); + cout << " b: " << b << endl; + + return 0; +#endif +} + +int test6() { +#ifdef XXX + SMatrix<float,4,2> A; + A(0,0) = A(0,1) = A(1,1) = A(2,0) = A(3,1) = 4.; + cout << "A: " << endl << A << endl; + + SMatrix<float,2,3> S; + S(0,0) = S(0,1) = S(1,1) = S(0,2) = 1.; + cout << " S: " << endl << S << endl; + + SMatrix<float,4,3> C = A * S; + cout << " C: " << endl << C << endl; + + return 0; +#endif +} + +int test7() { +#ifdef XXX + SVector<float,3> xv(4,4,4); + SVector<float,3> yv(5,5,5); + SVector<float,2> zv(64,64); + SMatrix<float,2,3> x; + x.Place_in_row(xv,0,0); + x.Place_in_row(xv,1,0); + SMatrix<float,2,3> y; + y.Place_in_row(yv,0,0); + y.Place_in_row(yv,1,0); + SMatrix<float,2,3> z; + z.Place_in_col(zv,0,0); + z.Place_in_col(zv,0,1); + z.Place_in_col(zv,0,2); + + // element wise multiplication + cout << "x * y: " << endl << times(x, -y) << endl; + + x += z - y; + cout << "x += z - y: " << endl << x << endl; + + // element wise square root + cout << "sqrt(z): " << endl << sqrt(z) << endl; + + // element wise multiplication with constant + cout << "2 * y: " << endl << 2 * y << endl; + + // a more complex expression + cout << "fabs(-z + 3*x): " << endl << fabs(-z + 3*x) << endl; + + return 0; +#endif +} + +int test8() { +#ifdef XXX + SMatrix<float,2,3> A; + SVector<float,3> av1(5.,15.,5.); + SVector<float,3> av2(15.,5.,15.); + A.Place_in_row(av1,0,0); + A.Place_in_row(av2,1,0); + + cout << "A: " << endl << A << endl; + + SVector<float,3> x(1,2,3); + SVector<float,3> y(4,5,6); + + cout << "dot(x,y): " << Dot(x,y) << endl; + + cout << "mag(x): " << Mag(x) << endl; + + cout << "cross(x,y): " << Cross(x,y) << endl; + + cout << "unit(x): " << Unit(x) << endl; + + SVector<float,3> z(4,16,64); + cout << "x + y: " << x+y << endl; + + cout << "x * y: " << x * -y << endl; + x += z - y; + cout << "x += z - y: " << x << endl; + + // element wise square root + cout << "sqrt(z): " << sqrt(z) << endl; + + // element wise multiplication with constant + cout << "2 * y: " << 2 * y << endl; + + // a more complex expression + cout << "fabs(-z + 3*x): " << fabs(-z + 3*x) << endl; + + SVector<float,4> a; + SVector<float,2> b(1,2); + a.Place_at(b,2); + cout << "a: " << a << endl; +#endif + + + return 0; +} + +#define TEST(N) \ + itest = N; \ + if (test##N() == 0) std::cout << " Test " << itest << " OK " << std::endl; \ + else {std::cout << " Test " << itest << " Failed " << std::endl; \ + return -1;} + + + +int main(void) { + + int itest; + TEST(1); + TEST(2); + TEST(3); + TEST(4); + TEST(5); + TEST(6); + TEST(7); + TEST(8); + + return 0; +} diff --git a/smatrix/test/test_smatrix.cxx b/smatrix/test/test_smatrix.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8434894032c33fa0f15d3656133c4c44f93d8c1c --- /dev/null +++ b/smatrix/test/test_smatrix.cxx @@ -0,0 +1,516 @@ +#include <iostream> +#include <cmath> +#include "Math/SVector.h" +#include "Math/SMatrix.h" + +using namespace ROOT::Math; + +using std::cout; +using std::endl; + +int main(void) { + + SVector<float,3> x(4,5,6); + SVector<float,2> y(2,3); + cout << "x: " << x << endl; + cout << "y: " << y << endl; + + SMatrix<float,4,3> A; + SMatrix<float,2,2> B; + + A.place_in_row(y, 1, 1); + A.place_in_col(x + 2, 1, 0); + A.place_at(B , 2, 1); + cout << "A: " << endl << A << endl; + + return 0; + +#ifdef XXX + SMatrix<double,3> A; + A(0,0) = A(1,0) = 1; + A(0,1) = 3; + A(1,1) = A(2,2) = 2; + cout << "A: " << endl << A << endl; + + SVector<double,3> x = A.row(0); + cout << "x: " << x << endl; + + SVector<double,3> y = A.col(1); + cout << "y: " << y << endl; + + return 0; +#endif + +#ifdef XXX + SMatrix<double,3> A; + A(0,0) = A(0,1) = A(1,0) = 1; + A(1,1) = A(2,2) = 2; + + SMatrix<double,3> B = A; // save A in B + cout << "A: " << endl << A << endl; + + double det = 0.; + A.sdet(det); + cout << "Determinant: " << det << endl; + // WARNING: A has changed!! + cout << "A again: " << endl << A << endl; + + A.sinvert(); + cout << "A^-1: " << endl << A << endl; + + // check if this is really the inverse: + cout << "A^-1 * B: " << endl << A * B << endl; + + return 0; +#endif + +#ifdef XXX + SMatrix<double,3> A; + A(0,0) = A(0,1) = A(1,0) = 1; + A(1,1) = A(2,2) = 2; + cout << " A: " << endl << A << endl; + + SVector<double,3> x(1,2,3); + cout << "x: " << x << endl; + + // we add 1 to each component of x and A + cout << " (x+1)^T * (A+1) * (x+1): " << product(x+1,A+1) << endl; + + return 0; +#endif + +#ifdef XXX + SMatrix<float,4,3> A; + A(0,0) = A(0,1) = A(1,1) = A(2,2) = 4.; + A(2,3) = 1.; + cout << "A: " << endl << A << endl; + SVector<float,4> x(1,2,3,4); + cout << " x: " << x << endl; + SVector<float,3> a(1,2,3); + cout << " a: " << a << endl; + SVector<float,4> y = x + A * a; + // SVector<float,4> y = A * a; + cout << " y: " << y << endl; + + SVector<float,3> b = (x+1) * (A+1); + cout << " b: " << b << endl; + + return 0; +#endif + +#ifdef XXX + SMatrix<float,4,2> A; + A(0,0) = A(0,1) = A(1,1) = A(2,0) = A(3,1) = 4.; + cout << "A: " << endl << A << endl; + + SMatrix<float,2,3> S; + S(0,0) = S(0,1) = S(1,1) = S(0,2) = 1.; + cout << " S: " << endl << S << endl; + + SMatrix<float,4,3> C = A * S; + cout << " C: " << endl << C << endl; + + return 0; +#endif + +#ifdef XXX + SMatrix<float,2,3> x = 4.; + SMatrix<float,2,3> y = 5.; + SMatrix<float,2,3> z = 64.; + + // element wise multiplication + cout << "x * y: " << endl << times(x, -y) << endl; + + x += z - y; + cout << "x += z - y: " << endl << x << endl; + + // element wise square root + cout << "sqrt(z): " << endl << sqrt(z) << endl; + + // element wise multiplication with constant + cout << "2 * y: " << endl << 2 * y << endl; + + // a more complex expression + cout << "fabs(-z + 3*x): " << endl << fabs(-z + 3*x) << endl; + + return 0; +#endif + +#ifdef XXX + SMatrix<float,2,3> A = 15.; + A(0,0) = A(1,1) = A(0,2) = 5.; + + cout << "A: " << endl << A << endl; + + SVector<float,3> x(1,2,3); + SVector<float,3> y(4,5,6); + + cout << "dot(x,y): " << dot(x,y) << endl; + + cout << "mag(x): " << mag(x) << endl; + + cout << "cross(x,y): " << cross(x,y) << endl; + + cout << "unit(x): " << unit(x) << endl; + + SVector<float,3> z(4,16,64); + cout << "x + y: " << x+y << endl; + + cout << "x * y: " << x * -y << endl; + x += z - y; + cout << "x += z - y: " << x << endl; + + // element wise square root + cout << "sqrt(z): " << sqrt(z) << endl; + + // element wise multiplication with constant + cout << "2 * y: " << 2 * y << endl; + + // a more complex expression + cout << "fabs(-z + 3*x): " << fabs(-z + 3*x) << endl; + + SVector<float,4> a; + SVector<float,2> b(1,2); + a.place_at(b,2); + cout << "a: " << a << endl; +#endif + + for(unsigned int i=0; i<1000000; ++i) { +#ifdef XXX + VtVector a(1.,2.,3.); + VtVector b(4.,5.,6.); + VtVector c(8.,9.,10.); + + VtVector d = a*(-1) + b; + VtVector d = a + b + c; +#endif +#ifdef XXX + VtMatrix A(4,3); + A(0,0) = A(1,1) = A(2,2) = 4.; + A(2,3) = 1.; + VtVector a(1,2,3); + // cout << " a: " << a << endl; + // cout << " A: " << A << endl; + // VtVector x(1,2,3,4); + // cout << " x: " << x << endl; + // VtVector y = x + A * a; + VtVector y = A * a; + cout << " y: " << y << endl; + exit(0); +#endif +#ifdef XXX + // ========================================== + VtMatrix A(3,3); + A(0,0) = A(1,1) = A(2,2) = 4.; + // A(2,3) = 1.; + // cout << " A: " << -A << endl; + VtMatrix B(3,3); + B(0,1) = B(1,0) = B(1,1) = B(0,2) = 1.; + // cout << " B: " << B << endl; + // cout << " B: " << B << endl; + VtMatrix C(3,3); + C(0,2) = C(1,2) = C(2,2) = 2.; + // cout << " C: " << C << endl; + // VtMatrix D = B + C + (-A); + VtMatrix D = A + B + C + A + B + C; + cout << " D: " << D << endl; + exit(0); +#endif +#ifdef XXX + VtSymMatrix VA(3,2.); + VA(0,0) = VA(0,1) = VA(1,0) = 1; + // cout << " A: " << VA << endl; + // cout << " det A: " << VA.det() << endl; + VA.det(); + VA.VtDsinv(); + cout << " A^-1: " << VA << endl; +#endif +#ifdef XXX + //=================================== + VtSymMatrix A(3,3.); + A(0,0) = A(0,1) = A(1,0) = 1; + // cout << " A: " << VA << endl; + VtSymMatrix B(3,3); + B(0,1) = B(1,0) = B(1,1) = B(2,2) = 1.; + // cout << " B: " << B << endl; + VtSymMatrix C(3,3); + C(0,1) = C(1,0) = C(2,1) = C(0,2) = 2.; + cout << " C: " << C << endl; + VtVector x(1,2,3); + // cout << " x: " << x << endl; + VtVector y(4,5,6); + // cout << " y: " << y << endl; + (A+B+C).product(x+y); + cout << " (x+y)^T * (A+B+C) * (x+y): " << (A+B+C).product(x+y) << endl; + exit(0); +#endif +#ifdef XXX + // cout << " c: " << c << endl; + SVector<float,3> a; + a[0] = 1.; a[1] = 2.; a[2] = 3.; + SVector<float,3> b; + b[0] = 4.; b[1] = 5.; b[2] = 6.; + SVector<float,3> c; + c[0] = 8.; c[1] = 9.; c[2] = 10.; + + SVector<float,3> d = a + b + c; + cout << "d: " << d << endl; + exit(0); + + cout << "d: " << d << endl; + d -= b + c; + cout << "d -= b + c: " << d << endl; + cout << "dot(a,b): " << dot(a,b) << endl; + cout << "dot(a+b,c+d): " << dot(a+b,c+d) << endl; + cout << "dot(a*b,c+d): " << dot(a*b,c+d) << endl; + cout << "dot(a*b+c,c+d): " << dot(a*b+c,c+d) << endl; + + cout << "mag2(a) " << mag2(a) << endl; + cout << "mag(a) " << mag(a) << endl; + cout << "mag2(a+b+c)" << mag2(a+b+c) << endl; + cout << "mag(a+b+c) " << mag(a+b+c) << endl; + // mag2(a); + // mag2(a+b+c); + + // SVector<float,3> d = a + static_cast<float>(3.); + // SVector<float,3> d = sqr(a + b + -20); + // SVector<float,3> d = (-a+b) * 3; + SVector<float,3> d = a * (b + c); + d = unit(a + b + c); + // d.unit(); + // cout << "d unit: " << d << endl; + // cout << "d = -a + b: " << d << endl; + // cout << "a: " << a << " b: " << b << endl; + // cout << "mag2(3*a): " << mag2(3*a) << endl; + // cout << "cross(3*a,b+c): " << cross(3*a,b+c) << endl; + // cout << "dot(-a,c+d+3): " << dot(-a,c+d+3) << endl; + // cout << "mag2(-a+d): " << mag2(-a+d) << " mag(d): " << mag(-a+d) << endl; + + SMatrix<float,3,3> A = 15.; + SMatrix<float,3,3> B = A; + A(0,0) = A(1,1) = A(2,0) = A(2,2) = 5.; + SMatrix<float,3,3> C = fabs(A + -B + 2); +// cout << "A: " << endl << A << endl; + cout << "C: " << endl << C << endl; +#endif + +#ifdef XXX + SMatrix<float,4,3> A; + A(0,0) = A(1,1) = A(2,2) = 4.; + A(2,3) = 1.; + // cout << "A: " << endl << A << endl; + SVector<float,4> x(1,2,3,4); + // cout << " x: " << x << endl; + SVector<float,3> a(1,2,3); + // cout << " a: " << a << endl; + SVector<float,4> y = x + A * a; + // SVector<float,4> y = A * a; + cout << " y: " << y << endl; + exit(0); +#endif +#ifdef XXX + // ======================================= + SMatrix<float,3,3> A; + A(0,0) = A(1,1) = A(2,2) = 4.; + // cout << "A: " << endl << A << endl; + // cout << "B: " << endl << B << endl; + SMatrix<float,3,3> B; + B(0,1) = B(1,0) = B(1,1) = B(0,2) = 1.; + // cout << "B: " << endl << B << endl; + // SMatrix<float,3,3> C = times(A,B); // component wise multiplication + SMatrix<float,3,3> C; + C(0,2) = C(1,2) = C(2,2) = 2.; + // cout << "C: " << endl << C << endl; + // SMatrix<float,3,3> D = -A + B + C; + SMatrix<float,3,3> D = A + B + C + A + B + C; + cout << "D: " << endl << D << endl; + exit(0); + SMatrix<float,3,2> E = 4.; + cout << "E: " << endl << E << endl; + // D = A + E; +#endif + +#ifdef XXX + SVector<float,3> b(4,5,6); + cout << " x: " << x << endl; + + // SVector<float,4> y = x + (A * 2) * (a + 1); + SVector<float,3> y = (x+1) * (A+1); + cout << " y: " << y << endl; + + SMatrix<float,3> S; + S(0,0) = S(1,0) = S(2,0) = 1.; + cout << " S: " << endl << S << endl; + SMatrix<float,4,3> C = A * S; + cout << " C: " << endl << C << endl; +#endif +#ifdef XXX + SMatrix<double,3> A; + A(0,0) = A(0,1) = A(1,0) = 1; + A(1,1) = A(2,2) = 2; + // cout << "A: " << endl << A << endl; + double det = 0.; + A.sdet(det); + cout << "Determinant: " << det << endl; + cout << "A again: " << endl << A << endl; + exit(0); + A.sinvert(); + cout << "A^-1: " << endl << A << endl; + exit(0); +#endif +#ifdef XXX + SVector<double,3> x(1,2,3); + cout << "x: " << x << endl; + cout << " x^T * A * x: " << product(x+1,A+1) << endl; + // product(A,x); + + SMatrix<double,3> B = 1; + cout << "B: " << endl << B << endl; + A /= B + 1; + cout << "A/=B: " << endl << A << endl; + + SVector<double,3> y(4,5,6); + cout << "y: " << y << endl; + y /= x; + cout << "y/=x: " << y << endl; + exit(0); +#endif +#ifdef XXX + //=================================== + SMatrix<float,3> A; + A(0,0) = A(0,1) = A(1,0) = 1; + A(1,1) = A(2,2) = 3.; + // cout << " A: " << endl << VA << endl; + SMatrix<float,3> B; + B(0,1) = B(1,0) = B(1,1) = B(2,2) = 1.; + B(0,0) = 3; + // cout << " B: " << endl << B << endl; + SMatrix<float,3> C; + C(0,1) = C(1,0) = C(2,1) = C(0,2) = 2.; + C(0,0) = C(1,1) = C(2,2) = 3; + // cout << " C: " << endl << C << endl; + SVector<float,3> x(1,2,3); + // cout << " x: " << x << endl; + SVector<float,3> y(4,5,6); + // cout << " y: " << y << endl; + product(A+B+C,x+y); + cout << " (x+y)^T * (A+B+C) * (x+y): " << product(A+B+C,x+y) << endl; + exit(0); +#endif +#ifdef XXX + SVector<float,4> x; + SVector<float,2> y(1,2); + // cout << "y: " << y << endl; + x.place_at(y,2); + cout << "x: " << x << endl; + SMatrix<float,4,3> A; + SMatrix<float,2,2> B = 1; + // SVector<float,2> x(1,2); + // A.place_in_row(x+2,1,1); + // A.place_in_col(x,1,1); + A.place_at(B,0,1); + cout << "A: " << endl << A << endl; + exit(0); +#endif +#ifdef XXX + VtVector x(4); + VtVector y(1,2); + // cout << "y: " << y << endl; + x.place_at(y,2); + cout << "x: " << x << endl; + exit(0); +#endif +#ifdef XXX + SMatrix<float,4,3> A; + SMatrix<float,2,2> B = 1; + // SVector<float,2> x(1,2); + // A.place_in_row(x+2,1,1); + // A.place_in_col(x,1,1); + A.place_at(B,0,1); + cout << "A: " << endl << A << endl; + exit(0); +#endif +#ifdef XXX + VtMatrix A(4,3); + VtMatrix B(2,2); + B(0,0) = B(1,1) = 2.; + A.place_at(B,0,1); + cout << "A: " << A << endl; + exit(0); +#endif +#ifdef XXX + SMatrix<float,3> C; + C(0,1) = C(1,0) = C(2,1) = C(0,2) = 2.; + C(0,0) = C(1,1) = C(2,2) = 3; + // cout << " C: " << endl << C << endl; + float det = 0.; + // Dfact<SMatrix<float,3>,3,3>(C,det); + C.det(det); + cout << "Dfact(C): " << det << endl; + cout << "C after: " << endl << C << endl; + exit(0); +#endif +#ifdef XXX + SMatrix<float,4> C; + C(0,1) = C(1,0) = C(2,1) = C(0,2) = C(3,1) = C(2,3) = 2.; + C(0,0) = C(1,1) = C(2,2) = C(3,3) = 3; +// SMatrix<float,4> B(C); +// cout << " C: " << endl << C << endl; + Dinv<SMatrix<float,4>,4,4>(C); + cout << "C after: " << endl << C << endl; + SMatrix<float,4> D = B * C; + // cout.setf(ios::fixed); + cout << "D = B * C: " << endl << D << endl; + exit(0); +#endif +#ifdef XXX + SMatrix<float,2> C; + C(0,0) = C(1,1) = C(0,1) = 5.; + C(1,0) = 1; + SMatrix<float,2> B(C); + cout << " C: " << endl << C << endl; + if(Invert<0>::Dinv(C) ) { + cout << "C after: " << endl << C << endl; + SMatrix<float,2> D = C * B; + cout << " D: " << endl << D << endl; + } else { cerr << " inversion failed! " << endl; } + exit(0); +#endif +#ifdef XXX + SMatrix<float,3> C; + C(0,1) = C(1,1) = C(0,2) = C(2,2) = 5.; + C(0,0) = 10; + SMatrix<float,3> B(C); + cout << " C: " << endl << C << endl; + if(Invert<3>::Dinv(C)) { + cout << "C after: " << endl << C << endl; + SMatrix<float,3> D = B * C; + cout << "D: " << endl << D << endl; + } else { cerr << " inversion failed! " << endl; } + exit(0); +#endif +#ifdef XXX + SMatrix<float,4> C; + C(0,1) = C(1,0) = C(2,1) = C(0,2) = 2; + C(3,1) = 2; + C(2,3) = 2.; + C(0,0) = C(1,1) = C(2,2) = C(3,3) = 3; + // Invert<4>::Dinv<SMatrix<float,4>, 4>(C); + // C.invert(); + SMatrix<float,4> B(C); + cout << " C: " << endl << C << endl; + // if(Invert<4>::Dinv(C)) { + if(C.invert()) { + cout << "C after: " << endl << C << endl; + SMatrix<float,4> D = B * C; + cout.setf(ios::fixed); + cout << "D: " << endl << D << endl; + } else { cerr << " inversion failed! " << endl; } + + cout << "C+B: " << endl << C+B << endl; + exit(0); +#endif + } + + return 0; +}