source: src/vector_ops.cpp@ 215df0

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 215df0 was 215df0, checked in by Tillmann Crueger <crueger@…>, 15 years ago

Simplified some methods.

  • Property mode set to 100644
File size: 7.0 KB
Line 
1/*
2 * vector_ops.cpp
3 *
4 * Created on: Apr 1, 2010
5 * Author: crueger
6 */
7
8#include "vector.hpp"
9#include "Plane.hpp"
10#include "log.hpp"
11#include "verbose.hpp"
12#include "gslmatrix.hpp"
13#include "leastsquaremin.hpp"
14#include "info.hpp"
15#include "Helpers/fast_functions.hpp"
16#include "Exceptions/LinearDependenceException.hpp"
17#include "Exceptions/SkewException.hpp"
18
19#include <gsl/gsl_linalg.h>
20#include <gsl/gsl_matrix.h>
21#include <gsl/gsl_permutation.h>
22#include <gsl/gsl_vector.h>
23
24/**
25 * !@file
26 * These files defines several common operation on vectors that should not
27 * become part of the main vector class, because they are either to complex
28 * or need methods from other subsystems that should not be moved to
29 * the LinAlg-Subsystem
30 */
31
32/** Creates a new vector as the one with least square distance to a given set of \a vectors.
33 * \param *vectors set of vectors
34 * \param num number of vectors
35 * \return true if success, false if failed due to linear dependency
36 */
37bool LSQdistance(Vector &res,const Vector **vectors, int num)
38{
39 int j;
40
41 for (j=0;j<num;j++) {
42 Log() << Verbose(1) << j << "th atom's vector: " << vectors[j] << endl;
43 }
44
45 int np = 3;
46 struct LSQ_params par;
47
48 const gsl_multimin_fminimizer_type *T =
49 gsl_multimin_fminimizer_nmsimplex;
50 gsl_multimin_fminimizer *s = NULL;
51 gsl_vector *ss, *y;
52 gsl_multimin_function minex_func;
53
54 size_t iter = 0, i;
55 int status;
56 double size;
57
58 /* Initial vertex size vector */
59 ss = gsl_vector_alloc (np);
60 y = gsl_vector_alloc (np);
61
62 /* Set all step sizes to 1 */
63 gsl_vector_set_all (ss, 1.0);
64
65 /* Starting point */
66 par.vectors = vectors;
67 par.num = num;
68
69 for (i=NDIM;i--;)
70 gsl_vector_set(y, i, (vectors[0]->at(i) - vectors[1]->at(i))/2.);
71
72 /* Initialize method and iterate */
73 minex_func.f = &LSQ;
74 minex_func.n = np;
75 minex_func.params = (void *)&par;
76
77 s = gsl_multimin_fminimizer_alloc (T, np);
78 gsl_multimin_fminimizer_set (s, &minex_func, y, ss);
79
80 do
81 {
82 iter++;
83 status = gsl_multimin_fminimizer_iterate(s);
84
85 if (status)
86 break;
87
88 size = gsl_multimin_fminimizer_size (s);
89 status = gsl_multimin_test_size (size, 1e-2);
90
91 if (status == GSL_SUCCESS)
92 {
93 printf ("converged to minimum at\n");
94 }
95
96 printf ("%5d ", (int)iter);
97 for (i = 0; i < (size_t)np; i++)
98 {
99 printf ("%10.3e ", gsl_vector_get (s->x, i));
100 }
101 printf ("f() = %7.3f size = %.3f\n", s->fval, size);
102 }
103 while (status == GSL_CONTINUE && iter < 100);
104
105 for (i=(size_t)np;i--;)
106 res[i] = gsl_vector_get(s->x, i);
107 gsl_vector_free(y);
108 gsl_vector_free(ss);
109 gsl_multimin_fminimizer_free (s);
110
111 return true;
112};
113
114/** Rotates the vector relative to the origin around the axis given by \a *axis by an angle of \a alpha.
115 * \param *axis rotation axis
116 * \param alpha rotation angle in radian
117 */
118Vector RotateVector(const Vector &vec,const Vector &axis, const double alpha)
119{
120 Vector a,y;
121 Vector res;
122 // normalise this vector with respect to axis
123 a = vec;
124 a.ProjectOntoPlane(axis);
125 // construct normal vector
126 try {
127 y = Plane(axis,a,0).getNormal();
128 }
129 catch (MathException &excp) {
130 // The normal vector cannot be created if there is linar dependency.
131 // Then the vector to rotate is on the axis and any rotation leads to the vector itself.
132 return vec;
133 }
134 y.Scale(vec.Norm());
135 // scale normal vector by sine and this vector by cosine
136 y.Scale(sin(alpha));
137 a.Scale(cos(alpha));
138 res = vec.Projection(axis);
139 // add scaled normal vector onto this vector
140 res += y;
141 // add part in axis direction
142 res += a;
143 return res;
144};
145
146/** Calculates the intersection of the two lines that are both on the same plane.
147 * This is taken from Weisstein, Eric W. "Line-Line Intersection." From MathWorld--A Wolfram Web Resource. http://mathworld.wolfram.com/Line-LineIntersection.html
148 * \param *out output stream for debugging
149 * \param *Line1a first vector of first line
150 * \param *Line1b second vector of first line
151 * \param *Line2a first vector of second line
152 * \param *Line2b second vector of second line
153 * \return true - \a this will contain the intersection on return, false - lines are parallel
154 */
155Vector GetIntersectionOfTwoLinesOnPlane(const Vector &Line1a, const Vector &Line1b, const Vector &Line2a, const Vector &Line2b)
156{
157 Info FunctionInfo(__func__);
158
159 Vector res;
160
161 auto_ptr<GSLMatrix> M = auto_ptr<GSLMatrix>(new GSLMatrix(4,4));
162
163 M->SetAll(1.);
164 for (int i=0;i<3;i++) {
165 M->Set(0, i, Line1a[i]);
166 M->Set(1, i, Line1b[i]);
167 M->Set(2, i, Line2a[i]);
168 M->Set(3, i, Line2b[i]);
169 }
170
171 //Log() << Verbose(1) << "Coefficent matrix is:" << endl;
172 //for (int i=0;i<4;i++) {
173 // for (int j=0;j<4;j++)
174 // cout << "\t" << M->Get(i,j);
175 // cout << endl;
176 //}
177 if (fabs(M->Determinant()) > MYEPSILON) {
178 Log() << Verbose(1) << "Determinant of coefficient matrix is NOT zero." << endl;
179 throw SkewException(__FILE__,__LINE__);
180 }
181
182 Log() << Verbose(1) << "INFO: Line1a = " << Line1a << ", Line1b = " << Line1b << ", Line2a = " << Line2a << ", Line2b = " << Line2b << "." << endl;
183
184
185 // constuct a,b,c
186 Vector a = Line1b - Line1a;
187 Vector b = Line2b - Line2a;
188 Vector c = Line2a - Line1a;
189 Vector d = Line2b - Line1b;
190 Log() << Verbose(1) << "INFO: a = " << a << ", b = " << b << ", c = " << c << "." << endl;
191 if ((a.NormSquared() < MYEPSILON) || (b.NormSquared() < MYEPSILON)) {
192 res.Zero();
193 Log() << Verbose(1) << "At least one of the lines is ill-defined, i.e. offset equals second vector." << endl;
194 throw LinearDependenceException(__FILE__,__LINE__);
195 }
196
197 // check for parallelity
198 Vector parallel;
199 double factor = 0.;
200 if (fabs(a.ScalarProduct(b)*a.ScalarProduct(b)/a.NormSquared()/b.NormSquared() - 1.) < MYEPSILON) {
201 parallel = Line1a - Line2a;
202 factor = parallel.ScalarProduct(a)/a.Norm();
203 if ((factor >= -MYEPSILON) && (factor - 1. < MYEPSILON)) {
204 res = Line2a;
205 Log() << Verbose(1) << "Lines conincide." << endl;
206 return res;
207 } else {
208 parallel = Line1a - Line2b;
209 factor = parallel.ScalarProduct(a)/a.Norm();
210 if ((factor >= -MYEPSILON) && (factor - 1. < MYEPSILON)) {
211 res = Line2b;
212 Log() << Verbose(1) << "Lines conincide." << endl;
213 return res;
214 }
215 }
216 Log() << Verbose(1) << "Lines are parallel." << endl;
217 res.Zero();
218 throw LinearDependenceException(__FILE__,__LINE__);
219 }
220
221 // obtain s
222 double s;
223 Vector temp1, temp2;
224 temp1 = c;
225 temp1.VectorProduct(b);
226 temp2 = a;
227 temp2.VectorProduct(b);
228 Log() << Verbose(1) << "INFO: temp1 = " << temp1 << ", temp2 = " << temp2 << "." << endl;
229 if (fabs(temp2.NormSquared()) > MYEPSILON)
230 s = temp1.ScalarProduct(temp2)/temp2.NormSquared();
231 else
232 s = 0.;
233 Log() << Verbose(1) << "Factor s is " << temp1.ScalarProduct(temp2) << "/" << temp2.NormSquared() << " = " << s << "." << endl;
234
235 // construct intersection
236 res = a;
237 res.Scale(s);
238 res += Line1a;
239 Log() << Verbose(1) << "Intersection is at " << res << "." << endl;
240
241 return res;
242};
Note: See TracBrowser for help on using the repository browser.