Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
parabola.cpp
Go to the documentation of this file.
1/*
2Copyright (c) 2001 I. B. Smirnov
3
4Permission to use, copy, modify, distribute and sell this file
5and its documentation for any purpose is hereby granted without fee,
6provided that the above copyright notice, this permission notice,
7and notices about any modifications of the original text
8appear in all copies and in supporting documentation.
9It is provided "as is" without express or implied warranty.
10*/
17
18namespace Heed {
19
20Parabola::Parabola(const Parabola& f) { *this = f; }
21
22Parabola::Parabola(double x[3], double y[3]) {
23 mfunname("Parabola::Parabola(double x[3], double y[3])");
24
25 check_econd12a(x[0], ==, x[1], "x[2]=" << x[2] << " y[0]=" << y[0] << " y[1]="
26 << y[1] << " y[2]=" << y[2] << '\n',
27 mcerr);
28 check_econd12a(x[0], ==, x[2], "x[1]=" << x[1] << " y[0]=" << y[0] << " y[1]="
29 << y[1] << " y[2]=" << y[2] << '\n',
30 mcerr);
31 check_econd12a(x[1], ==, x[2], "x[0]=" << x[0] << " y[0]=" << y[0] << " y[1]="
32 << y[1] << " y[2]=" << y[2] << '\n',
33 mcerr);
34 DynArr<DoubleAc> mat(3, 3);
37 for (int i = 0; i < 3; ++i) {
38 f[i] = y[i];
39 mat.ac(i, 2) = 1.0;
40 mat.ac(i, 1) = x[i];
41 mat.ac(i, 0) = x[i] * x[i];
42 }
43 int ierr;
44 int szero;
45 DynArr<DoubleAc> mat_inv;
46 inverse_DynArr_prot(mat, mat_inv, szero, ierr);
47 // check_econd11a( ierr, != 0 , "should never happen\n", mcerr );
48 if (ierr == 0) {
49 par = mat_inv * f;
50 da = par[0];
51 db = par[1];
52 dc = par[2];
53 } else {
54 da = 0.0;
55 DynLinArr<int> s_var(3);
56 s_var[0] = 0;
57 s_var[1] = 1;
58 s_var[2] = 1;
59 DynArr<DoubleAc> mat_inv1(3, 3);
60 // int ierr1;
61 // inverse_DynArr(mat, s_var, mat_inv, ierr, mat_inv1, ierr1);
62 inverse_DynArr_prot(mat, s_var, mat_inv, szero, ierr);
63 if (ierr != 0) {
64 // what if x1 and x2 are the same but the both differ from x0
65 // Then the following should help:
66 mat.ac(1, 1) = mat.ac(0, 1);
67 mat.ac(1, 2) = mat.ac(0, 2);
68 f[1] = f[0];
69 s_var[0] = 0;
70 s_var[1] = 1;
71 s_var[2] = 1;
72 inverse_DynArr_prot(mat, s_var, mat_inv, szero, ierr);
73 check_econd11a(ierr, != 0,
74 "should never happen\nmat=" << mat << "\ns_var=" << s_var
75 << "\nmat_inv=" << mat_inv,
76 mcerr);
77 }
78 par = mat_inv * f;
79 db = par[1];
80 dc = par[2];
81 }
82}
83
84Parabola::Parabola(double x1, double x2, double x3, double y1, double y2,
85 double y3)
86 : s_det(0), s_dxzero(0) {
87 mfunname("Parabola::Parabola(double x[3], double y[3])");
88
89 check_econd12a(x1, ==, x2, "x3=" << x3 << " y1=" << y1 << " y2=" << y2
90 << " y3=" << y3 << '\n',
91 mcerr);
92 check_econd12a(x1, ==, x3, "x2=" << x2 << " y1=" << y1 << " y2=" << y2
93 << " y3=" << y3 << '\n',
94 mcerr);
95 check_econd12a(x2, ==, x3, "x1=" << x1 << " y1=" << y1 << " y2=" << y2
96 << " y3=" << y3 << '\n',
97 mcerr);
98 DynArr<DoubleAc> mat(3, 3);
101 f[0] = y1;
102 mat.ac(0, 2) = 1.0;
103 mat.ac(0, 1) = x1;
104 mat.ac(0, 0) = x1 * x1;
105 f[1] = y2;
106 mat.ac(1, 2) = 1.0;
107 mat.ac(1, 1) = x2;
108 mat.ac(1, 0) = x2 * x2;
109 f[2] = y3;
110 mat.ac(2, 2) = 1.0;
111 mat.ac(2, 1) = x3;
112 mat.ac(2, 0) = x3 * x3;
113
114 int ierr;
115 int szero;
116 DynArr<DoubleAc> mat_inv;
117 inverse_DynArr_prot(mat, mat_inv, szero, ierr);
118 // check_econd11a( ierr, != 0 , "should never happen\n", mcerr );
119 if (ierr == 0) {
120 par = mat_inv * f;
121 da = par[0];
122 db = par[1];
123 dc = par[2];
124 } else {
125 da = 0.0;
126 DynLinArr<int> s_var(3);
127 s_var[0] = 0;
128 s_var[1] = 1;
129 s_var[2] = 1;
130 DynArr<DoubleAc> mat_inv1(3, 3);
131 // int ierr1;
132 // inverse_DynArr(mat, s_var, mat_inv, ierr, mat_inv1, ierr1);
133 inverse_DynArr_prot(mat, s_var, mat_inv, szero, ierr);
134 if (ierr != 0) {
135 // what if x1 and x2 are the same but the both differ from x0
136 // Then the following should help:
137 mat.ac(1, 1) = mat.ac(0, 1);
138 mat.ac(1, 2) = mat.ac(0, 2);
139 f[1] = f[0];
140 s_var[0] = 0;
141 s_var[1] = 1;
142 s_var[2] = 1;
143 inverse_DynArr_prot(mat, s_var, mat_inv, szero, ierr);
144 check_econd11a(ierr, != 0,
145 "should never happen\nmat=" << mat << "\ns_var=" << s_var
146 << "\nmat_inv=" << mat_inv,
147 mcerr);
148 }
149 par = mat_inv * f;
150 db = par[1];
151 dc = par[2];
152 }
153}
154
155Parabola::Parabola(double x[3], double y[3], int /*ii*/) {
156 mfunname("Parabola::Parabola(double x[3], double y[3], int)");
157
158 check_econd12(x[0], ==, x[1], mcerr);
159 // check_econd12( x[0] , == , x[2] , mcerr);
160 // check_econd12( x[1] , == , x[2] , mcerr);
161
162 DynArr<DoubleAc> mat(3, 3);
163 DynLinArr<DoubleAc> par(3);
165 for (int i = 0; i < 3; ++i) f[i] = y[i];
166 for (int i = 0; i < 2; ++i) {
167 mat.ac(i, 2) = 1.0;
168 mat.ac(i, 1) = x[i];
169 mat.ac(i, 0) = x[i] * x[i];
170 }
171 mat.ac(2, 2) = 0.0;
172 mat.ac(2, 1) = 1.0;
173 mat.ac(2, 0) = 2.0 * x[2];
174 int ierr;
175 int szero;
176 DynArr<DoubleAc> mat_inv;
177 inverse_DynArr_prot(mat, mat_inv, szero, ierr);
178 check_econd11a(ierr, != 0, "should never happen\n", mcerr);
179 par = mat_inv * f;
180 if (fabs(par[0]) == 0.0) {
181 da = 0.0;
182 } else {
183 da = par[0];
184 db = par[1];
185 dc = par[2];
186 }
187}
188
189int Parabola::find_zero(double xzero[2]) const {
190 mfunnamep("int Parabola::find_zero(double xzero[2]) const");
191 const Parabola& t = (*this);
192 if (s_dxzero == 0) {
193 // mcout<<"Parabola::find_zero: s_dxzero == 0\n";
194 t.s_dxzero = 1;
195 if (da == 0.0) {
196 if (db == 0.0) {
197 funnw.ehdr(mcerr);
198 mcerr << "can not find zero\n";
199 spexit(mcerr);
200 } else {
201 t.qdxzero = 1;
202 t.dxzero[0] = -dc / db;
203 }
204 } else {
205 if (determinant() < 0.0) {
206 t.qdxzero = 0;
207 t.dxzero[0] = 0;
208 t.dxzero[1] = 0;
209 } else if (determinant() == 0.0) {
210 t.qdxzero = 1;
211 t.dxzero[0] = -db / (2.0 * da);
212 } else {
213 const double sq = sqrt(determinant());
214 t.qdxzero = 2;
215 if (da > 0.0) {
216 t.dxzero[0] = (-db - sq) / (2.0 * da);
217 t.dxzero[1] = (-db + sq) / (2.0 * da);
218 } else {
219 t.dxzero[1] = (-db - sq) / (2.0 * da);
220 t.dxzero[0] = (-db + sq) / (2.0 * da);
221 }
222 // mcout<<"Parabola::find_zero: t.dxzero[0]="<<t.dxzero[0]
223 // <<" dxzero[0]="<<dxzero[0]<<'\n';
224 // mcout<<"Parabola::find_zero: t.dxzero[1]="<<t.dxzero[1]
225 // <<" dxzero[1]="<<dxzero[1]<<'\n';
226 }
227 }
228 }
229 xzero[0] = dxzero[0];
230 xzero[1] = dxzero[1];
231 return qdxzero;
232}
233
235 mfunname("double Parabola::find_maxmin(void)");
236 check_econd11(da, == 0, mcerr);
237 return -db / (2.0 * da);
238}
239
240std::ostream& operator<<(std::ostream& file, const Parabola& f) {
241 double xz[2];
242 int q = f.find_zero(xz);
243 Ifile << "Parabola: a=" << f.a() << " b=" << f.b() << " c=" << f.c()
244 << " qxzero=" << q;
245 if (q > 0) file << " xzero=" << xz[0];
246 if (q > 1) file << ' ' << xz[1];
247 file << '\n';
248 return file;
249}
250}
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:155
#define check_econd11a(a, signb, add, stream)
Definition: FunNameStack.h:172
#define check_econd12a(a, sign, b, add, stream)
Definition: FunNameStack.h:181
#define mfunnamep(string)
Definition: FunNameStack.h:49
#define spexit(stream)
Definition: FunNameStack.h:256
#define check_econd12(a, sign, b, stream)
Definition: FunNameStack.h:163
#define mfunname(string)
Definition: FunNameStack.h:45
T & ac(long i)
Definition: AbsArr.h:1700
Solution of a quadratic equation.
Definition: parabola.h:19
double c() const
Definition: parabola.h:23
int find_zero(double xzero[2]) const
Definition: parabola.cpp:189
double determinant() const
Definition: parabola.h:66
double a() const
Definition: parabola.h:21
Parabola()=default
Default constructor.
double find_maxmin()
Definition: parabola.cpp:234
double b() const
Definition: parabola.h:22
Definition: BGMesh.cpp:6
std::ostream & operator<<(std::ostream &file, const BGMesh &bgm)
Definition: BGMesh.cpp:37
void inverse_DynArr_prot(const DynArr< DoubleAc > &mi, DynArr< DoubleAc > &mr, int &szero, int &serr, int s_stop)
Definition: inverse.cpp:17
DoubleAc fabs(const DoubleAc &f)
Definition: DoubleAc.h:615
DoubleAc sqrt(const DoubleAc &f)
Definition: DoubleAc.cpp:314
#define Ifile
Definition: prstream.h:195
#define mcerr
Definition: prstream.h:128