00001 #include "RecoVertex/KinematicFitPrimitives/interface/MultipleKinematicConstraint.h"
00002
00003 void MultipleKinematicConstraint::addConstraint(KinematicConstraint * newConst) const
00004 {
00005 if(newConst == 0)throw VertexException("MultipleKinematicConstraint::zero constraint pointer passed");
00006 cts.push_back(newConst);
00007 em = false;
00008 }
00009
00010 pair<AlgebraicVector,AlgebraicVector> MultipleKinematicConstraint::value(const AlgebraicVector& exPoint) const
00011 {
00012 if(cts.size() == 0)throw VertexException("MultipleKinematicConstraint::value requested for empty constraint");
00013 if(exPoint.num_row() ==0 ) throw VertexException("MultipleKinematicConstraint::value requested for zero Linearization point");
00014
00015
00016
00017
00018 AlgebraicVector expansion = exPoint;
00019 int inSize = exPoint.num_row();
00020 if((inSize%7) !=0) throw VertexException("MultipleKinematicConstraint::linearization point has a wrong dimension");
00021
00022 int total = 0;
00023 for(vector<KinematicConstraint *>::const_iterator i = cts.begin(); i != cts.end(); i++)
00024 {total += (*i)->numberOfEquations();}
00025 AlgebraicVector vl(total,0);
00026
00027 int cr_size = 0;
00028 for(vector<KinematicConstraint *>::const_iterator i = cts.begin(); i != cts.end(); i++)
00029 {
00030 AlgebraicVector vlc = (*i)->value(expansion).first;
00031 int sz = vlc.num_row();
00032 for(int j = 1; j < sz+1; j++)
00033 {vl(cr_size+j) = vlc(j);}
00034 cr_size += sz;
00035 }
00036 return pair<AlgebraicVector, AlgebraicVector>(vl,expansion);
00037 }
00038
00039 pair<AlgebraicMatrix, AlgebraicVector> MultipleKinematicConstraint::derivative(const AlgebraicVector& exPoint) const
00040 {
00041 if(cts.size() == 0) throw VertexException("MultipleKinematicConstraint::derivative requested for empty constraint");
00042 if(exPoint.num_row() ==0 ) throw VertexException("MultipleKinematicConstraint::value requested for zero Linearization point");
00043
00044
00045 AlgebraicVector expansion = exPoint;
00046 int inSize = exPoint.num_row();
00047 if((inSize%7) !=0) throw VertexException("MultipleKinematicConstraint::linearization point has a wrong dimension");
00048
00049
00050 AlgebraicVector par = exPoint;
00051 int total = 0;
00052 for(vector<KinematicConstraint *>::const_iterator i = cts.begin(); i != cts.end(); i++)
00053 {total += (*i)->numberOfEquations();}
00054
00055
00056 AlgebraicMatrix dr(total,inSize);
00057
00058 int cr_size = 0;
00059 for(vector<KinematicConstraint *>::const_iterator i = cts.begin(); i != cts.end(); i++)
00060 {
00061
00062 AlgebraicMatrix lConst = (*i)->derivative(par).first;
00063 dr.sub(cr_size+1,1,lConst);
00064 cr_size += (*i)->numberOfEquations();
00065 }
00066 return pair<AlgebraicMatrix, AlgebraicVector>(dr,par);
00067 }
00068
00069 int MultipleKinematicConstraint::numberOfEquations() const
00070 {
00071 int ne = 0;
00072 if(cts.size() == 0) throw VertexException("MultipleKinematicConstraint::number of equations requested for empty constraint");
00073 for(vector<KinematicConstraint *>::const_iterator i = cts.begin(); i != cts.end(); i++)
00074 {ne += (*i)->numberOfEquations();}
00075 return ne;
00076 }
00077
00078 pair<AlgebraicVector, AlgebraicVector> MultipleKinematicConstraint::value(const vector<RefCountedKinematicParticle> par) const
00079 {
00080 if(cts.size() == 0) throw VertexException("MultipleKinematicConstraint::derivative requested for empty constraint");
00081 int nStates = par.size();
00082 AlgebraicVector param(7*nStates,0);
00083 int count = 1;
00084 for(vector<RefCountedKinematicParticle>::const_iterator i = par.begin(); i!=par.end(); i++)
00085 {
00086 for(int j = 1; j<8; j++){param((count -1)*7+j) = (*i)->currentState().kinematicParameters().vector()(j);}
00087 count++;
00088 }
00089
00090
00091 int total = 0;
00092 for(vector<KinematicConstraint *>::const_iterator i = cts.begin(); i != cts.end(); i++)
00093 {total += (*i)->numberOfEquations();}
00094 AlgebraicVector vl(total,0);
00095
00096 int cr_size = 0;
00097 for(vector<KinematicConstraint *>::const_iterator i = cts.begin(); i != cts.end(); i++)
00098 {
00099 AlgebraicVector vlc = (*i)->value(par).first;
00100 int sz = vlc.num_row();
00101 for(int j = 1; j <= sz; j++)
00102 {vl(cr_size+j) = vlc(j);}
00103 cr_size += sz;
00104 }
00105 return pair<AlgebraicVector, AlgebraicVector>(vl,param);
00106 }
00107
00108 pair<AlgebraicMatrix, AlgebraicVector> MultipleKinematicConstraint::derivative(const vector<RefCountedKinematicParticle> par) const
00109 {
00110 if(cts.size() == 0) throw VertexException("MultipleKinematicConstraint::derivative requested for empty constraint");
00111 int nStates = par.size();
00112 AlgebraicVector param(7*nStates,0);
00113
00114 int count = 1;
00115 for(vector<RefCountedKinematicParticle>::const_iterator i = par.begin(); i!=par.end(); i++)
00116 {
00117 for(int j = 1; j<8; j++){param((count -1)*7+j) = (*i)->currentState().kinematicParameters().vector()(j);}
00118 count++;
00119 }
00120 int total = 0;
00121 for(vector<KinematicConstraint *>::const_iterator i = cts.begin(); i != cts.end(); i++)
00122 {total += (*i)->numberOfEquations();}
00123 AlgebraicMatrix dr(total,7*nStates);
00124
00125 int cr_size = 0;
00126 for(vector<KinematicConstraint *>::const_iterator i = cts.begin(); i != cts.end(); i++)
00127 {
00128
00129
00130
00131 AlgebraicMatrix lConst = (*i)->derivative(param).first;
00132
00133
00134 dr.sub(cr_size+1,1,lConst);
00135 cr_size += (*i)->numberOfEquations();
00136 }
00137 return pair<AlgebraicMatrix, AlgebraicVector>(dr,param);
00138 }
00139
00140 AlgebraicVector MultipleKinematicConstraint::deviations(int nStates) const
00141 {
00142 AlgebraicVector dev(nStates*7,0);
00143 if(cts.size() == 0) throw VertexException("MultipleKinematicConstraint::deviations requested for empty constraint");
00144 for(vector<KinematicConstraint *>::const_iterator i = cts.begin(); i != cts.end(); i++)
00145 {
00146 AlgebraicVector dev_loc =(*i)->deviations(nStates);
00147 for(int j = 1; j < nStates*7+1; j++){dev(j) = dev(j) + dev_loc(j);}
00148 }
00149 return dev;
00150 }
00151