source: src/Tesselation/ellipsoid.cpp@ b4f72c

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since b4f72c was 94d5ac6, checked in by Frederik Heber <heber@…>, 12 years ago

FIX: As we use GSL internally, we are as of now required to use GPL v2 license.

  • GNU Scientific Library is used at every place in the code, especially the sub-package LinearAlgebra is based on it which in turn is used really everywhere in the remainder of MoleCuilder. Hence, we have to use the GPL license for the whole of MoleCuilder. In effect, GPL's COPYING was present all along and stated the terms of the GPL v2 license.
  • Hence, I added the default GPL v2 disclaimer to every source file and removed the note about a (actually missing) LICENSE file.
  • also, I added a help-redistribute action which again gives the disclaimer of the GPL v2.
  • also, I changed in the disclaimer that is printed at every program start in builder_init.cpp.
  • TEST: Added check on GPL statement present in every module to test CodeChecks project-disclaimer.
  • Property mode set to 100644
File size: 18.2 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * ellipsoid.cpp
25 *
26 * Created on: Jan 20, 2009
27 * Author: heber
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35#include "CodePatterns/MemDebug.hpp"
36
37#include <gsl/gsl_multimin.h>
38#include <gsl/gsl_vector.h>
39
40#include <iomanip>
41
42#include <set>
43
44#include "CodePatterns/Log.hpp"
45#include "ellipsoid.hpp"
46#include "LinearAlgebra/Vector.hpp"
47#include "LinearAlgebra/RealSpaceMatrix.hpp"
48#include "LinkedCell/linkedcell.hpp"
49#include "Tesselation/BoundaryPointSet.hpp"
50#include "Tesselation/boundary.hpp"
51#include "Tesselation/tesselation.hpp"
52
53#include "RandomNumbers/RandomNumberGeneratorFactory.hpp"
54#include "RandomNumbers/RandomNumberGenerator.hpp"
55
56/** Determines squared distance for a given point \a x to surface of ellipsoid.
57 * \param x given point
58 * \param EllipsoidCenter center of ellipsoid
59 * \param EllipsoidLength[3] three lengths of half axis of ellipsoid
60 * \param EllipsoidAngle[3] three rotation angles of ellipsoid
61 * \return squared distance from point to surface
62 */
63double SquaredDistanceToEllipsoid(Vector &x, Vector &EllipsoidCenter, double *EllipsoidLength, double *EllipsoidAngle)
64{
65 Vector helper, RefPoint;
66 double distance = -1.;
67 RealSpaceMatrix Matrix;
68 double InverseLength[3];
69 double psi,theta,phi; // euler angles in ZX'Z'' convention
70
71 //LOG(3, "Begin of SquaredDistanceToEllipsoid");
72
73 for(int i=0;i<3;i++)
74 InverseLength[i] = 1./EllipsoidLength[i];
75
76 // 1. translate coordinate system so that ellipsoid center is in origin
77 RefPoint = helper = x - EllipsoidCenter;
78 //LOG(4, "Translated given point is at " << RefPoint << ".");
79
80 // 2. transform coordinate system by inverse of rotation matrix and of diagonal matrix
81 psi = EllipsoidAngle[0];
82 theta = EllipsoidAngle[1];
83 phi = EllipsoidAngle[2];
84 Matrix.set(0,0, cos(psi)*cos(phi) - sin(psi)*cos(theta)*sin(phi));
85 Matrix.set(1,0, -cos(psi)*sin(phi) - sin(psi)*cos(theta)*cos(phi));
86 Matrix.set(2,0, sin(psi)*sin(theta));
87 Matrix.set(0,1, sin(psi)*cos(phi) + cos(psi)*cos(theta)*sin(phi));
88 Matrix.set(1,1, cos(psi)*cos(theta)*cos(phi) - sin(psi)*sin(phi));
89 Matrix.set(2,1, -cos(psi)*sin(theta));
90 Matrix.set(0,2, sin(theta)*sin(phi));
91 Matrix.set(1,2, sin(theta)*cos(phi));
92 Matrix.set(2,2, cos(theta));
93 helper *= Matrix;
94 helper.ScaleAll(InverseLength);
95 //LOG(4, "Transformed RefPoint is at " << helper << ".");
96
97 // 3. construct intersection point with unit sphere and ray between origin and x
98 helper.Normalize(); // is simply normalizes vector in distance direction
99 //LOG(4, "Transformed intersection is at " << helper << ".");
100
101 // 4. transform back the constructed intersection point
102 psi = -EllipsoidAngle[0];
103 theta = -EllipsoidAngle[1];
104 phi = -EllipsoidAngle[2];
105 helper.ScaleAll(EllipsoidLength);
106 Matrix.set(0,0, cos(psi)*cos(phi) - sin(psi)*cos(theta)*sin(phi));
107 Matrix.set(1,0, -cos(psi)*sin(phi) - sin(psi)*cos(theta)*cos(phi));
108 Matrix.set(2,0, sin(psi)*sin(theta));
109 Matrix.set(0,1, sin(psi)*cos(phi) + cos(psi)*cos(theta)*sin(phi));
110 Matrix.set(1,1, cos(psi)*cos(theta)*cos(phi) - sin(psi)*sin(phi));
111 Matrix.set(2,1, -cos(psi)*sin(theta));
112 Matrix.set(0,2, sin(theta)*sin(phi));
113 Matrix.set(1,2, sin(theta)*cos(phi));
114 Matrix.set(2,2, cos(theta));
115 helper *= Matrix;
116 //LOG(4, "Intersection is at " << helper << ".");
117
118 // 5. determine distance between backtransformed point and x
119 distance = RefPoint.DistanceSquared(helper);
120 //LOG(4, "Squared distance between intersection and RefPoint is " << distance << ".");
121
122 return distance;
123 //LOG(3, "End of SquaredDistanceToEllipsoid");
124};
125
126/** structure for ellipsoid minimisation containing points to fit to.
127 */
128struct EllipsoidMinimisation {
129 int N; //!< dimension of vector set
130 Vector *x; //!< array of vectors
131};
132
133/** Sum of squared distance to ellipsoid to be minimised.
134 * \param *x parameters for the ellipsoid
135 * \param *params EllipsoidMinimisation with set of data points to minimise distance to and dimension
136 * \return sum of squared distance, \sa SquaredDistanceToEllipsoid()
137 */
138double SumSquaredDistance (const gsl_vector * x, void * params)
139{
140 Vector *set= ((struct EllipsoidMinimisation *)params)->x;
141 int N = ((struct EllipsoidMinimisation *)params)->N;
142 double SumDistance = 0.;
143 double distance;
144 Vector Center;
145 double EllipsoidLength[3], EllipsoidAngle[3];
146
147 // put parameters into suitable ellipsoid form
148 for (int i=0;i<3;i++) {
149 Center[i] = gsl_vector_get(x, i+0);
150 EllipsoidLength[i] = gsl_vector_get(x, i+3);
151 EllipsoidAngle[i] = gsl_vector_get(x, i+6);
152 }
153
154 // go through all points and sum distance
155 for (int i=0;i<N;i++) {
156 distance = SquaredDistanceToEllipsoid(set[i], Center, EllipsoidLength, EllipsoidAngle);
157 if (!isnan(distance)) {
158 SumDistance += distance;
159 } else {
160 SumDistance = GSL_NAN;
161 break;
162 }
163 }
164
165 //LOG(0, "Current summed distance is " << SumDistance << ".");
166 return SumDistance;
167};
168
169/** Finds best fitting ellipsoid parameter set in Least square sense for a given point set.
170 * \param *out output stream for debugging
171 * \param *set given point set
172 * \param N number of points in set
173 * \param EllipsoidParamter[3] three parameters in ellipsoid equation
174 * \return true - fit successful, false - fit impossible
175 */
176bool FitPointSetToEllipsoid(Vector *set, int N, Vector *EllipsoidCenter, double *EllipsoidLength, double *EllipsoidAngle)
177{
178 int status = GSL_SUCCESS;
179 LOG(2, "Begin of FitPointSetToEllipsoid ");
180 if (N >= 3) { // check that enough points are given (9 d.o.f.)
181 struct EllipsoidMinimisation par;
182 const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
183 gsl_multimin_fminimizer *s = NULL;
184 gsl_vector *ss, *x;
185 gsl_multimin_function minex_func;
186
187 size_t iter = 0;
188 double size;
189
190 /* Starting point */
191 x = gsl_vector_alloc (9);
192 for (int i=0;i<3;i++) {
193 gsl_vector_set (x, i+0, EllipsoidCenter->at(i));
194 gsl_vector_set (x, i+3, EllipsoidLength[i]);
195 gsl_vector_set (x, i+6, EllipsoidAngle[i]);
196 }
197 par.x = set;
198 par.N = N;
199
200 /* Set initial step sizes */
201 ss = gsl_vector_alloc (9);
202 for (int i=0;i<3;i++) {
203 gsl_vector_set (ss, i+0, 0.1);
204 gsl_vector_set (ss, i+3, 1.0);
205 gsl_vector_set (ss, i+6, M_PI/20.);
206 }
207
208 /* Initialize method and iterate */
209 minex_func.n = 9;
210 minex_func.f = &SumSquaredDistance;
211 minex_func.params = (void *)&par;
212
213 s = gsl_multimin_fminimizer_alloc (T, 9);
214 gsl_multimin_fminimizer_set (s, &minex_func, x, ss);
215
216 do {
217 iter++;
218 status = gsl_multimin_fminimizer_iterate(s);
219
220 if (status)
221 break;
222
223 size = gsl_multimin_fminimizer_size (s);
224 status = gsl_multimin_test_size (size, 1e-2);
225
226 if (status == GSL_SUCCESS) {
227 for (int i=0;i<3;i++) {
228 EllipsoidCenter->at(i) = gsl_vector_get (s->x,i+0);
229 EllipsoidLength[i] = gsl_vector_get (s->x, i+3);
230 EllipsoidAngle[i] = gsl_vector_get (s->x, i+6);
231 }
232 LOG(4, setprecision(3) << "Converged fit at: " << *EllipsoidCenter << ", lengths " << EllipsoidLength[0] << ", " << EllipsoidLength[1] << ", " << EllipsoidLength[2] << ", angles " << EllipsoidAngle[0] << ", " << EllipsoidAngle[1] << ", " << EllipsoidAngle[2] << " with summed distance " << s->fval << ".");
233 }
234
235 } while (status == GSL_CONTINUE && iter < 1000);
236
237 gsl_vector_free(x);
238 gsl_vector_free(ss);
239 gsl_multimin_fminimizer_free (s);
240
241 } else {
242 LOG(3, "Not enough points provided for fit to ellipsoid.");
243 return false;
244 }
245 LOG(2, "End of FitPointSetToEllipsoid");
246 if (status == GSL_SUCCESS)
247 return true;
248 else
249 return false;
250};
251
252/** Picks a number of random points from a LC neighbourhood as a fitting set.
253 * \param *out output stream for debugging
254 * \param *T Tesselation containing boundary points
255 * \param *LC linked cell list of all atoms
256 * \param *&x random point set on return (not allocated!)
257 * \param PointsToPick number of points in set to pick
258 */
259void PickRandomNeighbouredPointSet(class Tesselation *T, class LinkedCell_deprecated *LC, Vector *&x, size_t PointsToPick)
260{
261 size_t PointsLeft = 0;
262 size_t PointsPicked = 0;
263 int Nlower[NDIM], Nupper[NDIM];
264 set<int> PickedAtomNrs; // ordered list of picked atoms
265 set<int>::iterator current;
266 int index;
267 TesselPoint *Candidate = NULL;
268 LOG(2, "Begin of PickRandomPointSet");
269
270 // allocate array
271 if (x == NULL) {
272 x = new Vector[PointsToPick];
273 } else {
274 ELOG(2, "Given pointer to vector array seems already allocated.");
275 }
276
277 RandomNumberGenerator &random = RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator("mt19937", "uniform_int");
278 // check that random number generator's bounds are ok
279 ASSERT(random.min() == 0,
280 "PickRandomNeighbouredPointSet: Chosen RandomNumberGenerator's min "
281 +toString(random.min())+" is not 0!");
282 ASSERT(random.max() >= LC->N[0],
283 "PickRandomNeighbouredPointSet: Chosen RandomNumberGenerator's max "
284 +toString(random.max())+" is too small"+toString(LC->N[0])
285 +" for axis 0!");
286 ASSERT(random.max() >= LC->N[1],
287 "PickRandomNeighbouredPointSet: Chosen RandomNumberGenerator's max "
288 +toString(random.max())+" is too small"+toString(LC->N[1])
289 +" for axis 1!");
290 ASSERT(random.max() >= LC->N[2],
291 "PickRandomNeighbouredPointSet: Chosen RandomNumberGenerator's max "
292 +toString(random.max())+" is too small"+toString(LC->N[2])
293 +" for axis 2!");
294
295 do {
296 for(int i=0;i<NDIM;i++) // pick three random indices
297 LC->n[i] = ((int)random() % LC->N[i]);
298 LOG(2, "INFO: Center cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << ".");
299 // get random cell
300 const TesselPointSTLList *List = LC->GetCurrentCell();
301 if (List == NULL) { // set index to it
302 continue;
303 }
304 LOG(2, "INFO: Cell index is No. " << LC->index << ".");
305
306 if (DoLog(2)) {
307 std::stringstream output;
308 output << "LC Intervals:";
309 for (int i=0;i<NDIM;i++)
310 output << " [" << Nlower[i] << "," << Nupper[i] << "] ";
311 LOG(2, output.str());
312 }
313
314 for (int i=0;i<NDIM;i++) {
315 Nlower[i] = ((LC->n[i]-1) >= 0) ? LC->n[i]-1 : 0;
316 Nupper[i] = ((LC->n[i]+1) < LC->N[i]) ? LC->n[i]+1 : LC->N[i]-1;
317 }
318
319 // count whether there are sufficient atoms in this cell+neighbors
320 PointsLeft=0;
321 for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)
322 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
323 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
324 const TesselPointSTLList *List = LC->GetCurrentCell();
325 PointsLeft += List->size();
326 }
327 LOG(2, "There are " << PointsLeft << " atoms in this neighbourhood.");
328 if (PointsLeft < PointsToPick) { // ensure that we can pick enough points in its neighbourhood at all.
329 continue;
330 }
331
332 // pre-pick a fixed number of atoms
333 PickedAtomNrs.clear();
334 do {
335 index = (((int)random()) % PointsLeft);
336 current = PickedAtomNrs.find(index); // not present?
337 if (current == PickedAtomNrs.end()) {
338 //LOG(2, "Picking atom Nr. " << index << ".");
339 PickedAtomNrs.insert(index);
340 }
341 } while (PickedAtomNrs.size() < PointsToPick);
342
343 index = 0; // now go through all and pick those whose from PickedAtomsNr
344 PointsPicked=0;
345 current = PickedAtomNrs.begin();
346 for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)
347 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
348 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
349 const TesselPointSTLList *List = LC->GetCurrentCell();
350// LOG(2, "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << " containing " << List->size() << " points.");
351 if (List != NULL) {
352// if (List->begin() != List->end())
353// LOG(2, "Going through candidates ... ");
354// else
355// LOG(2, "Cell is empty ... ");
356 for (TesselPointSTLList::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) {
357 if ((current != PickedAtomNrs.end()) && (*current == index)) {
358 Candidate = (*Runner);
359 LOG(2, "Current picked node is " << (*Runner)->getName() << " with index " << index << ".");
360 x[PointsPicked++] = Candidate->getPosition(); // we have one more atom picked
361 current++; // next pre-picked atom
362 }
363 index++; // next atom Nr.
364 }
365// } else {
366// LOG(2, "List for this index not allocated!");
367 }
368 }
369 LOG(2, "The following points were picked: ");
370 for (size_t i=0;i<PointsPicked;i++)
371 LOG(2, x[i]);
372 if (PointsPicked == PointsToPick) // break out of loop if we have all
373 break;
374 } while(1);
375
376 LOG(2, "End of PickRandomPointSet");
377};
378
379/** Picks a number of random points from a set of boundary points as a fitting set.
380 * \param *out output stream for debugging
381 * \param *T Tesselation containing boundary points
382 * \param *&x random point set on return (not allocated!)
383 * \param PointsToPick number of points in set to pick
384 */
385void PickRandomPointSet(class Tesselation *T, Vector *&x, size_t PointsToPick)
386{
387 size_t PointsLeft = (size_t) T->PointsOnBoundaryCount;
388 size_t PointsPicked = 0;
389 double value, threshold;
390 PointMap *List = &T->PointsOnBoundary;
391 LOG(2, "Begin of PickRandomPointSet");
392
393 // allocate array
394 if (x == NULL) {
395 x = new Vector[PointsToPick];
396 } else {
397 ELOG(2, "Given pointer to vector array seems already allocated.");
398 }
399
400 RandomNumberGenerator &random = RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator("mt19937", "uniform_int");
401 const double rng_min = random.min();
402 const double rng_max = random.max();
403 if (List != NULL)
404 for (PointMap::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
405 threshold = 1. - (double)(PointsToPick - PointsPicked)/(double)PointsLeft;
406 value = (double)random()/(double)(rng_max-rng_min);
407 if (value > threshold) {
408 x[PointsPicked] = (Runner->second->node->getPosition());
409 PointsPicked++;
410 //LOG(3, "Current node is " << *Runner->second->node << " with " << value << " ... " << threshold << ": IN.");
411 } else {
412 //LOG(3, "Current node is " << *Runner->second->node << " with " << value << " ... " << threshold << ": OUT.");
413 }
414 PointsLeft--;
415 }
416 LOG(2, "The following points were picked: ");
417 for (size_t i=0;i<PointsPicked;i++)
418 LOG(3, x[i]);
419
420 LOG(2, "End of PickRandomPointSet");
421};
422
423/** Finds best fitting ellipsoid parameter set in least square sense for a given point set.
424 * \param *out output stream for debugging
425 * \param *T Tesselation containing boundary points
426 * \param *LCList linked cell list of all atoms
427 * \param N number of unique points in ellipsoid fit, must be greater equal 6
428 * \param number of fits (i.e. parameter sets in output file)
429 * \param *filename name for output file
430 */
431void FindDistributionOfEllipsoids(class Tesselation *T, class LinkedCell_deprecated *LCList, int N, int number, const char *filename)
432{
433 ofstream output;
434 Vector *x = NULL;
435 Vector Center;
436 Vector EllipsoidCenter;
437 double EllipsoidLength[3];
438 double EllipsoidAngle[3];
439 double distance, MaxDistance, MinDistance;
440 LOG(0, "Begin of FindDistributionOfEllipsoids");
441
442 // construct center of gravity of boundary point set for initial ellipsoid center
443 Center.Zero();
444 for (PointMap::iterator Runner = T->PointsOnBoundary.begin(); Runner != T->PointsOnBoundary.end(); Runner++)
445 Center += (Runner->second->node->getPosition());
446 Center.Scale(1./T->PointsOnBoundaryCount);
447 LOG(4, "DEBUG: Center of PointsOnBoundary is at " << Center << ".");
448
449 // Output header
450 output.open(filename, ios::trunc);
451 output << "# Nr.\tCenterX\tCenterY\tCenterZ\ta\tb\tc\tpsi\ttheta\tphi" << endl;
452
453 // loop over desired number of parameter sets
454 for (;number >0;number--) {
455 LOG(1, "Determining data set " << number << " ... ");
456 // pick the point set
457 x = NULL;
458 //PickRandomPointSet(T, LCList, x, N);
459 PickRandomNeighbouredPointSet(T, LCList, x, N);
460
461 // calculate some sensible starting values for parameter fit
462 MaxDistance = 0.;
463 MinDistance = x[0].ScalarProduct(x[0]);
464 for (int i=0;i<N;i++) {
465 distance = x[i].ScalarProduct(x[i]);
466 if (distance > MaxDistance)
467 MaxDistance = distance;
468 if (distance < MinDistance)
469 MinDistance = distance;
470 }
471 //LOG(2, "MinDistance " << MinDistance << ", MaxDistance " << MaxDistance << ".");
472 EllipsoidCenter = Center; // use Center of Gravity as initial center of ellipsoid
473 for (int i=0;i<3;i++)
474 EllipsoidAngle[i] = 0.;
475 EllipsoidLength[0] = sqrt(MaxDistance);
476 EllipsoidLength[1] = sqrt((MaxDistance+MinDistance)/2.);
477 EllipsoidLength[2] = sqrt(MinDistance);
478
479 // fit the parameters
480 if (FitPointSetToEllipsoid(x, N, &EllipsoidCenter, &EllipsoidLength[0], &EllipsoidAngle[0])) {
481 LOG(1, "Picking succeeded!");
482 // output obtained parameter set
483 output << number << "\t";
484 for (int i=0;i<3;i++)
485 output << setprecision(9) << EllipsoidCenter[i] << "\t";
486 for (int i=0;i<3;i++)
487 output << setprecision(9) << EllipsoidLength[i] << "\t";
488 for (int i=0;i<3;i++)
489 output << setprecision(9) << EllipsoidAngle[i] << "\t";
490 output << endl;
491 } else { // increase N to pick one more
492 LOG(1, "Picking failed!");
493 number++;
494 }
495 delete[](x); // free allocated memory for point set
496 }
497 // close output and finish
498 output.close();
499
500 LOG(0, "End of FindDistributionOfEllipsoids");
501};
Note: See TracBrowser for help on using the repository browser.