LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
Solver.cxx File Reference
#include "Solver.h"
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <set>
#include <iostream>

Go to the source code of this file.

Functions

template<class T >
sqr (T x)
 
double Metric (double q, double p)
 
QuadExpr Metric (double q, QuadExpr p)
 
double Metric (const std::vector< SpaceCharge * > &scs, double alpha)
 
double Metric (const std::vector< CollectionWireHit * > &cwires, double alpha)
 
QuadExpr Metric (const SpaceCharge *sci, const SpaceCharge *scj, double alpha)
 
QuadExpr Metric (const SpaceCharge *sc, double alpha)
 
double SolvePair (CollectionWireHit *cwire, SpaceCharge *sci, SpaceCharge *scj, double alpha)
 
void Iterate (CollectionWireHit *cwire, double alpha)
 
void Iterate (SpaceCharge *sc, double alpha)
 
void Iterate (const std::vector< CollectionWireHit * > &cwires, const std::vector< SpaceCharge * > &orphanSCs, double alpha)
 

Function Documentation

void Iterate ( CollectionWireHit cwire,
double  alpha 
)

Definition at line 263 of file Solver.cxx.

References SpaceCharge::AddCharge(), CollectionWireHit::fCrossings, SolvePair(), and x.

Referenced by Iterate(), and reco3d::SpacePointSolver::Minimize().

264 {
265  // Consider all pairs of crossings
266  const unsigned int N = cwire->fCrossings.size();
267 
268  for(unsigned int i = 0; i+1 < N; ++i){
269  SpaceCharge* sci = cwire->fCrossings[i];
270 
271  for(unsigned int j = i+1; j < N; ++j){
272  SpaceCharge* scj = cwire->fCrossings[j];
273 
274  const double x = SolvePair(cwire, sci, scj, alpha);
275 
276  if(x == 0) continue;
277 
278  // Actually make the update
279  sci->AddCharge(+x);
280  scj->AddCharge(-x);
281  } // end for j
282  } // end for i
283 }
Float_t x
Definition: compare.C:6
void AddCharge(double dq)
Definition: Solver.cxx:35
std::vector< SpaceCharge * > fCrossings
Definition: Solver.h:73
double SolvePair(CollectionWireHit *cwire, SpaceCharge *sci, SpaceCharge *scj, double alpha)
Definition: Solver.cxx:217
void Iterate ( SpaceCharge sc,
double  alpha 
)

Definition at line 286 of file Solver.cxx.

References SpaceCharge::AddCharge(), QuadExpr::Eval(), SpaceCharge::fPred, QuadExpr::Linear(), max, Metric(), QuadExpr::Quadratic(), and x.

287 {
288  const QuadExpr chisq = Metric(sc, alpha);
289 
290  // Find the minimum of a quadratic expression
291  double x = -chisq.Linear()/(2*chisq.Quadratic());
292 
293  // Don't allow the SpaceCharge to go negative
294  const double xmin = -sc->fPred;
295 
296  // Clamp to allowed range
297  x = std::max(xmin, x);
298 
299  const double chisq_new = chisq.Eval(x);
300 
301  // Should try here too, because the function might be convex not concave, so
302  // d/dx=0 gives the max not the min, and the true min is at one extreme of
303  // the range.
304  const double chisq_n = chisq.Eval(xmin);
305 
306  if(chisq_n < chisq_new)
307  sc->AddCharge(xmin);
308  else
309  sc->AddCharge(x);
310 }
Float_t x
Definition: compare.C:6
void AddCharge(double dq)
Definition: Solver.cxx:35
double Linear() const
Definition: QuadExpr.h:16
Int_t max
Definition: plot.C:27
double Metric(double q, double p)
Definition: Solver.cxx:71
double Eval(double x) const
Definition: QuadExpr.cxx:67
double fPred
Definition: Solver.h:58
double Quadratic() const
Definition: QuadExpr.h:15
void Iterate ( const std::vector< CollectionWireHit * > &  cwires,
const std::vector< SpaceCharge * > &  orphanSCs,
double  alpha 
)

Definition at line 313 of file Solver.cxx.

References Iterate().

316 {
317  // Visiting in a "random" order helps prevent local artefacts that are slow
318  // to break up.
319  unsigned int cwireIdx = 0;
320  do{
321  Iterate(cwires[cwireIdx], alpha);
322 
323  const unsigned int prime = 1299827;
324  cwireIdx = (cwireIdx+prime)%cwires.size();
325  } while(cwireIdx != 0);
326 
327  for(SpaceCharge* sc: orphanSCs) Iterate(sc, alpha);
328 }
void Iterate(CollectionWireHit *cwire, double alpha)
Definition: Solver.cxx:263
double Metric ( double  q,
double  p 
)

Definition at line 71 of file Solver.cxx.

References sqr().

Referenced by Iterate(), Metric(), reco3d::SpacePointSolver::Minimize(), and SolvePair().

72 {
73  return sqr(q-p);
74 }
T sqr(T x)
Definition: Solver.cxx:9
QuadExpr Metric ( double  q,
QuadExpr  p 
)

Definition at line 77 of file Solver.cxx.

References sqr().

78 {
79  return sqr(q-p);
80 }
T sqr(T x)
Definition: Solver.cxx:9
double Metric ( const std::vector< SpaceCharge * > &  scs,
double  alpha 
)

Definition at line 83 of file Solver.cxx.

References Metric(), and sqr().

84 {
85  double ret = 0;
86 
87  std::set<InductionWireHit*> iwires;
88  for(const SpaceCharge* sc: scs){
89  if(sc->fWire1) iwires.insert(sc->fWire1);
90  if(sc->fWire2) iwires.insert(sc->fWire2);
91 
92  if(alpha != 0){
93  ret -= alpha*sqr(sc->fPred);
94  // "Double-counting" of the two ends of the connection is
95  // intentional. Otherwise we'd have a half in the line above.
96  ret -= alpha * sc->fPred * sc->fNeiPotential;
97  }
98  }
99 
100  for(const InductionWireHit* iwire: iwires){
101  ret += Metric(iwire->fCharge, iwire->fPred);
102  }
103 
104  return ret;
105 }
double Metric(double q, double p)
Definition: Solver.cxx:71
T sqr(T x)
Definition: Solver.cxx:9
double Metric ( const std::vector< CollectionWireHit * > &  cwires,
double  alpha 
)

Definition at line 108 of file Solver.cxx.

References Metric().

109 {
110  std::vector<SpaceCharge*> scs;
111  for(CollectionWireHit* cwire: cwires)
112  scs.insert(scs.end(), cwire->fCrossings.begin(), cwire->fCrossings.end());
113  return Metric(scs, alpha);
114 }
double Metric(double q, double p)
Definition: Solver.cxx:71
QuadExpr Metric ( const SpaceCharge sci,
const SpaceCharge scj,
double  alpha 
)

Definition at line 117 of file Solver.cxx.

References InductionWireHit::fCharge, Neighbour::fCoupling, SpaceCharge::fNeighbours, SpaceCharge::fNeiPotential, InductionWireHit::fPred, SpaceCharge::fPred, Neighbour::fSC, SpaceCharge::fWire1, SpaceCharge::fWire2, Metric(), n, sqr(), x, and QuadExpr::X().

118 {
119  QuadExpr ret = 0;
120 
121  // How much charge moves from scj to sci
122  QuadExpr x = QuadExpr::X();
123 
124  if(alpha != 0){
125  const double scip = sci->fPred;
126  const double scjp = scj->fPred;
127 
128  // Self energy. SpaceCharges are never the same object
129  ret -= alpha*sqr(scip + x);
130  ret -= alpha*sqr(scjp - x);
131 
132  // Interaction. We're only seeing one end of the double-ended connection
133  // here, so multiply by two.
134  ret -= 2 * alpha * (scip + x) * sci->fNeiPotential;
135  ret -= 2 * alpha * (scjp - x) * scj->fNeiPotential;
136 
137  // This miscounts if i and j are neighbours of each other
138  for(const Neighbour& n: sci->fNeighbours){
139  if(n.fSC == scj){
140  // If we detect that case, remove the erroneous terms
141  ret += 2 * alpha * (scip + x) * scjp * n.fCoupling;
142  ret += 2 * alpha * (scjp - x) * scip * n.fCoupling;
143 
144  // And replace with the correct interaction terms
145  ret -= 2 * alpha * (scip + x) * (scjp - x) * n.fCoupling;
146  break;
147  }
148  }
149  }
150 
151 
152  const InductionWireHit* iwire1 = sci->fWire1;
153  const InductionWireHit* jwire1 = scj->fWire1;
154 
155  const double qi1 = iwire1 ? iwire1->fCharge : 0;
156  const double pi1 = iwire1 ? iwire1->fPred : 0;
157 
158  const double qj1 = jwire1 ? jwire1->fCharge : 0;
159  const double pj1 = jwire1 ? jwire1->fPred : 0;
160 
161  if(iwire1 == jwire1){
162  // Same wire means movement of charge cancels itself out
163  if(iwire1) ret += Metric(qi1, pi1);
164  }
165  else{
166  if(iwire1) ret += Metric(qi1, pi1 + x);
167  if(jwire1) ret += Metric(qj1, pj1 - x);
168  }
169 
170  const InductionWireHit* iwire2 = sci->fWire2;
171  const InductionWireHit* jwire2 = scj->fWire2;
172 
173  const double qi2 = iwire2 ? iwire2->fCharge : 0;
174  const double pi2 = iwire2 ? iwire2->fPred : 0;
175 
176  const double qj2 = jwire2 ? jwire2->fCharge : 0;
177  const double pj2 = jwire2 ? jwire2->fPred : 0;
178 
179  if(iwire2 == jwire2){
180  if(iwire2) ret += Metric(qi2, pi2);
181  }
182  else{
183  if(iwire2) ret += Metric(qi2, pi2 + x);
184  if(jwire2) ret += Metric(qj2, pj2 - x);
185  }
186 
187  return ret;
188 }
Float_t x
Definition: compare.C:6
double fCharge
Definition: Solver.h:25
double fPred
Definition: Solver.h:27
double fCoupling
Definition: Solver.h:37
std::vector< Neighbour > fNeighbours
Definition: Solver.h:56
double fNeiPotential
Neighbour-induced potential.
Definition: Solver.h:59
InductionWireHit * fWire2
Definition: Solver.h:54
static QuadExpr X()
Definition: QuadExpr.cxx:6
InductionWireHit * fWire1
Definition: Solver.h:54
double Metric(double q, double p)
Definition: Solver.cxx:71
T sqr(T x)
Definition: Solver.cxx:9
Char_t n[5]
double fPred
Definition: Solver.h:58
SpaceCharge * fSC
Definition: Solver.h:36
QuadExpr Metric ( const SpaceCharge sc,
double  alpha 
)

Definition at line 191 of file Solver.cxx.

References InductionWireHit::fCharge, SpaceCharge::fNeiPotential, InductionWireHit::fPred, SpaceCharge::fPred, SpaceCharge::fWire1, SpaceCharge::fWire2, Metric(), sqr(), x, and QuadExpr::X().

192 {
193  QuadExpr ret = 0;
194 
195  // How much charge is added to sc
196  QuadExpr x = QuadExpr::X();
197 
198  if(alpha != 0){
199  const double scp = sc->fPred;
200 
201  // Self energy
202  ret -= alpha*sqr(scp + x);
203 
204  // Interaction. We're only seeing one end of the double-ended connection
205  // here, so multiply by two.
206  ret -= 2 * alpha * (scp + x) * sc->fNeiPotential;
207  }
208 
209  // Prediction of the induction wires
210  ret += Metric(sc->fWire1->fCharge, sc->fWire1->fPred + x);
211  ret += Metric(sc->fWire2->fCharge, sc->fWire2->fPred + x);
212 
213  return ret;
214 }
Float_t x
Definition: compare.C:6
double fCharge
Definition: Solver.h:25
double fPred
Definition: Solver.h:27
double fNeiPotential
Neighbour-induced potential.
Definition: Solver.h:59
InductionWireHit * fWire2
Definition: Solver.h:54
static QuadExpr X()
Definition: QuadExpr.cxx:6
InductionWireHit * fWire1
Definition: Solver.h:54
double Metric(double q, double p)
Definition: Solver.cxx:71
T sqr(T x)
Definition: Solver.cxx:9
double fPred
Definition: Solver.h:58
double SolvePair ( CollectionWireHit cwire,
SpaceCharge sci,
SpaceCharge scj,
double  alpha 
)

Definition at line 217 of file Solver.cxx.

References QuadExpr::Eval(), SpaceCharge::fPred, QuadExpr::Linear(), max, Metric(), min, QuadExpr::Quadratic(), and x.

Referenced by Iterate().

220 {
221  const QuadExpr chisq = Metric(sci, scj, alpha);
222  const double chisq0 = chisq.Eval(0);
223 
224  // Find the minimum of a quadratic expression
225  double x = -chisq.Linear()/(2*chisq.Quadratic());
226 
227  // Don't allow either SpaceCharge to go negative
228  const double xmin = -sci->fPred;
229  const double xmax = scj->fPred;
230 
231  // Clamp to allowed range
232  x = std::min(xmax, x);
233  x = std::max(xmin, x);
234 
235  const double chisq_new = chisq.Eval(x);
236 
237  // Should try these too, because the function might be convex not concave, so
238  // d/dx=0 gives the max not the min, and the true min is at one extreme of
239  // the range.
240  const double chisq_p = chisq.Eval(xmax);
241  const double chisq_n = chisq.Eval(xmin);
242 
243  if(std::min(std::min(chisq_p, chisq_n), chisq_new) > chisq0+1){
244  std::cout << "Solution at " << x << " is worse than current state! Scan from " << xmin << " to " << xmax << std::endl;
245  for(double x = xmin; x < xmax; x += .01*(xmax-xmin)){
246  std::cout << x << " " << chisq.Eval(x) << std::endl;
247  }
248 
249  std::cout << "Soln, original, up edge, low edge:" << std::endl;
250  std::cout << chisq_new << " " << chisq0 << " " << chisq_p << " " << chisq_n << std::endl;
251  abort();
252  }
253 
254  if(std::min(chisq_n, chisq_p) < chisq_new){
255  if(chisq_n < chisq_p) return xmin;
256  return xmax;
257  }
258 
259  return x;
260 }
Float_t x
Definition: compare.C:6
double Linear() const
Definition: QuadExpr.h:16
Int_t max
Definition: plot.C:27
double Metric(double q, double p)
Definition: Solver.cxx:71
Int_t min
Definition: plot.C:26
double Eval(double x) const
Definition: QuadExpr.cxx:67
double fPred
Definition: Solver.h:58
double Quadratic() const
Definition: QuadExpr.h:15
template<class T >
T sqr ( x)

Definition at line 9 of file Solver.cxx.

References x.

Referenced by Metric().

9 {return x*x;}
Float_t x
Definition: compare.C:6