NeoPZ
TPZProjectEllipse.cpp
Go to the documentation of this file.
1 //
2 // TPZProjectEllipse.cpp
3 // PZ
4 //
5 // Created by Philippe Devloo on 11/4/13.
6 //
7 //
8 
9 #include "TPZProjectEllipse.h"
10 
17  int64_t npoints = fPoints.Rows();
18  int64_t dim = fPoints.Cols();
19  int nincog, i;
20  nincog = 2*dim;
21 
22  if(npoints<nincog) return false;
23 
24  // Dimensioning vector of coefficients
25  fcoefficients.Resize(nincog);
26  fcoefficients.Fill(0.);
27 
28  // Will be solved y^2 = p*x^2 + q*x + r*y + s
29  // Constructing matrix H and Transpose of H to compute by least squares method
30  TPZFMatrix<REAL> DeltaH;
31  TPZFMatrix<REAL> DeltaHTranspose;
32  TPZFMatrix<REAL> DifSol;
34 
35  // Redimensioning
36  A.Redim(nincog,nincog);
37  DeltaH.Redim(npoints,nincog);
38  DeltaHTranspose.Redim(nincog,npoints);
39  DifSol.Redim(npoints,1);
40 
41  if(dim == 2) {
42  // Filling y^2 into Coefficients
43  for(i=0;i<npoints;i++)
44  DifSol.PutVal(i,0,fPoints(i,1)*fPoints(i,1)); // fill y*y
45 
46  // Filling elements for H matrix
47  for(int i=0;i<npoints;i++) {
48  DeltaH.PutVal(i,0,fPoints(i,0)*fPoints(i,0)); // fill x*x
49  DeltaH.PutVal(i,1,fPoints(i,0)); // fill x
50  DeltaH.PutVal(i,2,fPoints(i,0)); // fill y
51  DeltaH.PutVal(i,3,1.); // fill 1.
52  }
53  }
54  else if(dim == 3) {
55  // Filling y^2 into Coefficients
56  for(i=0;i<npoints;i++)
57  DifSol.PutVal(i,0,fPoints(i,2)*fPoints(i,2)); // fill z*z
58 
59  // Filling elements for H matrix
60  for(int i=0;i<npoints;i++) {
61  DeltaH.PutVal(i,0,fPoints(i,0)*fPoints(i,0)); // fill x*x
62  DeltaH.PutVal(i,1,fPoints(i,0)); // fill x
63  DeltaH.PutVal(i,2,fPoints(i,1)*fPoints(i,1)); // fill y*y
64  DeltaH.PutVal(i,3,fPoints(i,1)); // fill y
65  DeltaH.PutVal(i,4,fPoints(i,2)); // fill z
66  DeltaH.PutVal(i,5,1.); // fill 1.
67  }
68  }
69  else
70  return false;
71 
72  // Solving by least squares using product of matrix: DeltaH_t * DifSol = DeltaH_t * DeltaH * Coeffs(u)
73  A.Zero();
74  DeltaH.Transpose(&DeltaHTranspose);
75  A = DeltaHTranspose*DeltaH;
76  TPZFMatrix<REAL> Coefficients;
77  Coefficients = DeltaHTranspose*DifSol;
78  A.SolveDirect(Coefficients,ELU);
79  for (int i=0; i<Coefficients.Rows(); i++) {
80  fcoefficients[i] = Coefficients(i,0);
81  }
82  return true;
83 }
84 
91  int dim = fPoints.Cols();
92  int64_t npoints = fPoints.Rows();
93  int nincog, i;
94  nincog = 2*dim+1+2*(dim-2);
95 
96  if(npoints<nincog) return false;
97 
98  // Dimensioning vector of coefficients
99  fcoefficients.Resize(nincog);
100  fcoefficients.Fill(0.);
101 
102  // Will be solved y^2 = p*x^2 + q*x + r*y + s
103  // Constructing matrix H and Transpose of H to compute by least squares method
104  TPZFMatrix<REAL> DeltaH;
105  TPZFMatrix<REAL> DeltaHTranspose;
106  TPZFMatrix<REAL> DifSol;
108 
109  // Redimensioning
110  A.Redim(nincog,nincog);
111  DeltaH.Redim(npoints,nincog);
112  DeltaHTranspose.Redim(nincog,npoints);
113  DifSol.Redim(npoints,1);
114 
115  if(dim == 2) {
116  // Filling y^2 into Coefficients
117  for(i=0;i<npoints;i++)
118  DifSol.PutVal(i,0,fPoints(i,1)*fPoints(i,1)); // fill y*y
119 
120  // Filling elements for H matrix
121  for(int i=0;i<npoints;i++) {
122  DeltaH.PutVal(i,0,fPoints(i,0)*fPoints(i,0)); // fill x*x
123  DeltaH.PutVal(i,1,fPoints(i,0)); // fill x
124  DeltaH.PutVal(i,2,fPoints(i,0)*fPoints(i,1)); // fill x*y
125  DeltaH.PutVal(i,3,fPoints(i,1)); // fill y
126  DeltaH.PutVal(i,4,1.); // fill 1.
127  }
128  }
129  else if(dim == 3) {
130  // Filling y^2 into Coefficients
131  for(i=0;i<npoints;i++)
132  DifSol.PutVal(i,0,fPoints(i,2)*fPoints(i,2)); // fill z*z
133 
134  // Filling elements for H matrix
135  for(int i=0;i<npoints;i++) {
136  DeltaH.PutVal(i,0,fPoints(i,0)*fPoints(i,0)); // fill x*x
137  DeltaH.PutVal(i,1,fPoints(i,0)); // fill x
138  DeltaH.PutVal(i,2,fPoints(i,1)*fPoints(i,1)); // fill y*y
139  DeltaH.PutVal(i,3,fPoints(i,1)); // fill y
140  DeltaH.PutVal(i,4,fPoints(i,0)*fPoints(i,1)); // fill x*y
141  DeltaH.PutVal(i,5,fPoints(i,2)); // fill z
142  DeltaH.PutVal(i,6,fPoints(i,1)*fPoints(i,2)); // fill y*z
143  DeltaH.PutVal(i,7,fPoints(i,0)*fPoints(i,2)); // fill x*z
144  DeltaH.PutVal(i,8,1.); // fill 1.
145  }
146  }
147  else
148  return false;
149 
150  // Solving by least squares using product of matrix: DeltaH_t * DifSol = DeltaH_t * DeltaH * Coeffs(u)
151  A.Zero();
152  DeltaH.Transpose(&DeltaHTranspose);
153  A = DeltaHTranspose*DeltaH;
154  TPZFMatrix<REAL> Coefficients;
155  Coefficients = DeltaHTranspose*DifSol;
156  A.SolveDirect(Coefficients,ELU);
157 
158  // Verifying that the equation corresponding a ellipse
159  REAL temp;
160  if(dim==2) {
161  temp = Coefficients(1,0)*Coefficients(1,0)/Coefficients(0,0);
162  temp -= (Coefficients(2,0)*Coefficients(2,0));
163  if(Coefficients(0,0) > 0 || (4*Coefficients(3,0)) < temp)
164  return false;
165  }
166  else { // It is not complete
167  temp = Coefficients(1,0)*Coefficients(1,0)/Coefficients(0,0);
168  if(Coefficients(0,0) > 0)
169  return false;
170  }
171  for (int i=0; i<Coefficients.Rows(); i++) {
172  fcoefficients[i] = Coefficients(i,0);
173  }
174  return true;
175 }
176 
177 
179  int64_t npoints = fPoints.Rows();
180  int nincog = 2, i;
181 
182  if(npoints<nincog) return false;
183 
184  // Dimensioning vector of coefficients
185  TPZFMatrix<REAL> Coefficients;
186  Coefficients.Redim(nincog,1);
187  Coefficients.Zero();
188 
189  // Will be solved y^2 = p*x^2 + q*x + r*y + s
190  // Constructing matrix H and Transpose of H to compute by least squares method
191  TPZFMatrix<REAL> DeltaH;
192  TPZFMatrix<REAL> DeltaHTranspose;
193  TPZFMatrix<REAL> DifSol;
195 
196  // Redimensioning
197  A.Redim(nincog,nincog);
198  DeltaH.Redim(npoints,nincog);
199  DeltaHTranspose.Redim(nincog,npoints);
200  DifSol.Redim(npoints,1);
201  // DifSol.Zero();
202 
203  // Filling y^2 into Coefficients
204  for(i=0;i<npoints;i++)
205  DifSol.PutVal(i,0,fPoints(i,1)*fPoints(i,1)); // fill y*y
206 
207  // Filling elements for H matrix
208  for(int i=0;i<npoints;i++) {
209  DeltaH.PutVal(i,0,fPoints(i,0)*fPoints(i,0)); // fill x*x
210  DeltaH.PutVal(i,1,1.); // fill 1.
211  }
212 
213 // DeltaH.Print(std::cout);
214 
215  // Solving by least squares using product of matrix: DeltaH_t * DifSol = DeltaH_t * DeltaH * Coeffs(u)
216  A.Zero();
217  DeltaH.Transpose(&DeltaHTranspose);
218  A = DeltaHTranspose*DeltaH;
219  Coefficients = DeltaHTranspose*DifSol;
220  A.SolveDirect(Coefficients,ELU);
221  for (int i=0; i<Coefficients.Rows(); i++) {
222  fcoefficients[i] = Coefficients(i,0);
223  }
224  return true;
225 }
226 
227 
228 
229 
230 /*********** Utilities *************/
231 
232 // To print as zero all the values almost zero
234  int nr, nc;
235  for(nr=0;nr<mat.Rows();nr++) {
236  for(nc=0;nc<mat.Cols();nc++) {
237  if(fabs(mat.GetVal(nr,nc)) < fTol)
238  mat.PutVal(nr,nc,0.);
239  }
240  }
241 }
243  int nr;
244  for(nr=0;nr<mat.NElements();nr++) {
245  if(fabs(mat[nr]) < fTol)
246  mat[nr] = 0.;
247  }
248 }
249 
251 void TPZProjectEllipse::PrintAxes(TPZFMatrix<REAL> &P,std::ostream &out) {
252  out << "\nPrinting axes of the ellipse:\n";
253  AlmostZeroToZero(P);
254  for(int i=0;i<P.Cols();i++) {
255  out << "Vector" << i+1 << " = ( ";
256  for(int j=0;j<P.Rows();j++) {
257  if(j) out << " , ";
258  out << P.GetVal(j,i);
259  }
260  out << " )\n";
261  }
262  out << std::endl;
263 }
264 
265 /****************** END Utilities ************************/
266 
267 
275  // int dim = Center.NElements();
276  int ncoeffs = fcoefficients.size();
277  REAL temp, temp1;
278  if(ncoeffs ==4) {
279  Center[0] = -(fcoefficients[1]/(2.*fcoefficients[0]));
280  Center[1] = 0.5*fcoefficients[2];
281  // Computing Ratios[1] in temp
283  // Computing Ratios
284  temp1 = temp/(4*fcoefficients[0]*fcoefficients[0]);
285  if(temp1 < 0. || IsZero(temp1))
286  return false;
287  Ratios[0] = sqrt(temp1);
288  temp1 = (-temp)/(4*fcoefficients[0]);
289  Ratios[1] = sqrt(temp1);
290  }
291  else if(ncoeffs == 6) {
292  Center[0] = -(fcoefficients[1]/(2.*fcoefficients[0]));
293  Center[1] = -(fcoefficients[3]/(2.*fcoefficients[2]));
294  Center[2] = 0.5*fcoefficients[4];
295  // Computing Ratios[2]
296  temp = fcoefficients[5]+(Center[2]*Center[2])-(Center[0]*Center[0]*fcoefficients[0])-(Center[1]*Center[1]*fcoefficients[2]);
297  if(temp < 0.) return false;
298  Ratios[2] = sqrt(temp);
299  // Computing Ratios[0] in Ratios[1]
300  temp = -(Ratios[2]*Ratios[2]/fcoefficients[2]);
301  if(temp < 0.) return false;
302  Ratios[1] = sqrt(temp);
303  temp = -(Ratios[2]*Ratios[2]/fcoefficients[0]);
304  if(temp < 0.) return false;
305  Ratios[0] = sqrt(temp);
306  }
307  else if(ncoeffs == 2)
308  {
309  Center[0] = 0.;
310  Center[1] = 0.;
311  // Computing Ratios[1] in temp
312  temp = fcoefficients[1]-(Center[0]*Center[0]*fcoefficients[0])+(Center[1]*Center[1]);
313  // Computing Ratios[0] in Ratios[1]
314  Ratios[1] = -temp/fcoefficients[0];
315  if(temp < 0. || Ratios[1] < 0.)
316  return false;
317  Ratios[0] = sqrt(Ratios[1]);
318  Ratios[1] = sqrt(temp);
319  }
320  return true;
321 }
322 
323 //void PrintingAsSimpleEquation(TPZVec<REAL> &Center,TPZVec<REAL> &Ratios,std::ostream &out);
324 
326  if(fcoefficients.size() == 2)
327  {
328  out << std::endl << "y*y = " << fcoefficients[0] << "x*x + " << fcoefficients[1] << "\n";
329  out << "\nElipse: (x - " << Center[0] << ")^2/" << Ratios[0]*Ratios[0] << " + (y - " << Center[1] << ")^2/" << Ratios[1]*Ratios[1] << " = 1.\n" << std::endl;
330 
331  }
332  else if(fcoefficients.size() == 4) {
333  out << std::endl << "y*y = " << fcoefficients[0] << "x*x + " << fcoefficients[1] << "x + " << fcoefficients[2] << "y + " << fcoefficients[3] << "\n";
334  out << "\nElipse: (x - " << Center[0] << ")^2/" << Ratios[0]*Ratios[0] << " + (y - " << Center[1] << ")^2/" << Ratios[1]*Ratios[1] << " = 1.\n" << std::endl;
335  }
336  else if(fcoefficients.size() == 6)
337  {
338  out << std::endl << "z*z = " << fcoefficients[0] << "x*x + " << fcoefficients[1] << "x + " << fcoefficients[2] << "y*y + " << fcoefficients[3] << "y +";
339  out << fcoefficients[4] << "z + " << fcoefficients[5] << std::endl;
340  out << "\nElipse: (x - " << Center[0] << ")^2/" << Ratios[0]*Ratios[0] << " + (y - " << Center[1] << ")^2/" << Ratios[1]*Ratios[1];
341  out << " + (z - " << Center[2] << ")^2/" << Ratios[2]*Ratios[2] << " = 1.\n" << std::endl;
342  }
343 }
344 
352 
353  int dim = fPoints.Cols();
354  TPZManVector<REAL> Center(dim,0.);
355  TPZManVector<REAL> Ratios(dim,0.);
356 
357  // Applying least squares for these five points
359  return false;
360  std::cout << "\n\nCoefficients after least square for quadratic equation:";
361 
362  // Making zero depending on Tolerance
363  float Tol;
364  ZeroTolerance(Tol);
365 
366  // Getting the values of the center and ratios for the ellipse from Coeffs values
367  if(!StandardFormatForSimpleEllipse(Center,Ratios))
368  return false;
369  PrintingAsSimpleEquation(Center,Ratios,std::cout);
370  return true;
371 }
372 
373 
375 
376  int dim = 2;
377  TPZManVector<REAL> Center(dim,0.);
378  TPZManVector<REAL> Ratios(dim,0.);
379 
380  // Applying least squares for these five points
382  std::cout << "\n\nSolution:";
383 
384  // Making zero depending on Tolerance
385  float Tol;
386  ZeroTolerance(Tol);
387 
388  // Getting the values of the center and ratios for the ellipse from Coeffs values
389  if(!StandardFormatForSimpleEllipse(Center,Ratios))
390  return false;
391  PrintingAsSimpleEquation(Center,Ratios,std::cout);
392  return true;
393 }
394 
403 
404  int dim = fPoints.Cols();
405  TPZManVector<REAL> Center(dim,0.);
406  TPZManVector<REAL> Ratios(dim,0.);
407  TPZManVector<REAL> VectorI(dim,0.);
408  TPZManVector<REAL> VectorJ(dim,0.);
409  TPZManVector<REAL> VectorK(dim,0.);
410  // Applying least squares for these five points
412  return false;
413 
414  // In case a12 = 0, then don't exist rotation then it is a ellipse with parallel axes to cartesian axes
415  if(dim==2 && IsZero(fcoefficients[2])) {
416  TPZManVector<REAL> NewCoeffs(4,0.);
417  NewCoeffs = fcoefficients;
418  // Making zero depending on Tolerance
419  float Tol;
420  ZeroTolerance(Tol);
421 
422  // Getting the values of the center and ratios for the ellipse from Coeffs values
423  if(!StandardFormatForSimpleEllipse(Center,Ratios))
424  return false;
425  PrintingAsSimpleEquation(Center,Ratios,std::cout);
426  return true;
427  }
428 
429  // Diagonalization of the quadratic form when Coeffs(2,0) is not null
430  TPZManVector<REAL> NewCoeffs;
431  DebugStop();
432  //DiagonalizingQuadraticForm(NewCoeffs,std::cout);
433 
434  // The coefficients are multiplied by (-1/lambda2)
435  if(dim==2) {
436  fcoefficients[0] = -(NewCoeffs[0]/NewCoeffs[2]);
437  fcoefficients[1] = -(NewCoeffs[1]/NewCoeffs[2]);
438  fcoefficients[2] = -(NewCoeffs[3]/NewCoeffs[2]);
439  fcoefficients[3] = -(NewCoeffs[4]/NewCoeffs[2]);
440  // Getting the values of the center and ratios for the ellipse from Coeffs values
441  if(!StandardFormatForSimpleEllipse(Center,Ratios))
442  return false;
443  PrintingAsSimpleEquation(Center,Ratios,std::cout);
444  }
445 
446  return true;
447 }
448 
452 /*
453  bool TPZProjectEllipse::DiagonalizingQuadraticForm(TPZVec<REAL> &NewCoeffs,std::ostream &out) {
454  int dim = fPoints.Cols();
455  NewCoeffs.resize(2*dim+1);
456  // Changing signal
457  fcoefficients *= (-1.);
458  // Constructing a symmetric matrix
459  TPZFMatrix<REAL> A(dim,dim);
460  if(dim == 2) {
461  A(0,0) = Coeffs(0,0);
462  A(0,1) = A(1,0) = 0.5*Coeffs(2,0);
463  A(1,1) = 1.;
464  }
465  else {
466  A(0,0) = Coeffs(0,0);
467  A(0,1) = A(1,0) = 0.5*Coeffs(4,0);
468  A(1,1) = Coeffs(2,0);
469  A(2,2) = 1.;
470  A(0,2) = A(2,0) = 0.5*Coeffs(7,0);
471  A(1,2) = A(2,1) = 0.5*Coeffs(6,0);
472  }
473 
474  // Store the coefficients of the variables in the homogenous equation
475  TPZFMatrix<REAL> B(dim,1);
476  int nr, nc;
477  REAL F = Coeffs.GetVal(4+(dim-2)*4,0);
478  for(nr=0;nr<dim;nr++)
479  B.PutVal(nr,0,Coeffs.GetVal(2*nr+1,0));
480 
481  // Computing eigenvalues and eigenvectors
482  TPZVec<REAL> Eigenvalues(dim);
483  Coeffs.Redim(dim,dim);
484  REAL Tol, temp, norm;
485  ZeroTolerance(Tol);
486  int64_t niter = 1000;
487 
488  if(!A.SolveEigensystemJacobi(niter,Tol,Eigenvalues,Coeffs))
489  return false; // Could be some eigenvector a null vector
490 
491  // Verifying Eigenvalues must to be positives to be ellipse or ellipsoid
492  for(nr=0;nr<dim;nr++) {
493  if(Eigenvalues[nr] > 0.) continue;
494  return false; // If some eigenvalue is zero it is parabole, if some of these are negative hyperbol
495  }
496  // Normalizing eigenvectors in matrix
497  for(nc=0;nc<dim;nc++) {
498  temp = 0.;
499  for(nr=0;nr<dim;nr++)
500  temp += Coeffs(nr,nc)*Coeffs(nr,nc);
501  norm = sqrt(temp);
502  for(nr=0;nr<dim;nr++)
503  Coeffs(nr,nc) *= (1./norm);
504  }
505  // The transpose of the ortogonal matrix is not necessary, it exists, is enough
506 
507  // Print the direction vectors for axes of the ellipse
508  PrintAxes(Coeffs,out);
509 
510  // Coefficients of the squares of the variables
511  for(nr=0;nr<dim;nr++)
512  NewCoeffs.PutVal(2*nr,0,Eigenvalues[nr]);
513 
514  // Coefficients of the variables (linear terms)
515  if(dim==2) {
516  temp = B(0,0)*Coeffs(0,0) + B(1,0)*Coeffs(0,1);
517  NewCoeffs.PutVal(1,0,temp);
518  temp = B(0,0)*Coeffs(1,0) + B(1,0)*Coeffs(1,1);
519  NewCoeffs.PutVal(3,0,temp);
520  NewCoeffs.PutVal(4,0,F);
521  }
522  else if(dim==3) {
523  temp = B(0,0)*Coeffs(0,0) + B(1,0)*Coeffs(0,1) + B(2,0)*Coeffs(0,2);
524  NewCoeffs.PutVal(1,0,temp);
525  //It is not complete
526  }
527 
528  return true;
529  }
530  */
expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ fabs
Definition: tfadfunc.h:140
bool IsZero(long double a)
Returns if the value a is close Zero as the allowable tolerance.
Definition: pzreal.h:668
void AlmostZeroToZero(TPZFMatrix< REAL > &mat)
virtual void Resize(const int64_t newsize, const T &object)
Resizes the vector object.
Definition: pzmanvector.h:426
void PrintingAsSimpleEquation(TPZVec< REAL > &Center, TPZVec< REAL > &Ratios, std::ostream &out)
int Zero() override
Makes Zero all the elements.
Definition: pzfmatrix.h:651
int64_t size() const
Returns the number of elements of the vector.
Definition: pzvec.h:196
void PrintAxes(TPZFMatrix< REAL > &P, std::ostream &out)
#define DebugStop()
Returns a message to user put a breakpoint in.
Definition: pzerror.h:20
Definition: pzmatrix.h:52
int64_t Rows() const
Returns number of rows.
Definition: pzmatrix.h:803
expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ sqrt
Definition: tfadfunc.h:120
int Redim(const int64_t newRows, const int64_t newCols) override
Redimension a matrix and ZERO your elements.
Definition: pzfmatrix.h:616
TPZManVector< REAL, 6 > fcoefficients
coefficients determined by the least squares problem
TPZFMatrix< REAL > fPoints
Points which determine the projection.
bool StandardFormatForSimpleEllipse(TPZVec< REAL > &Center, TPZVec< REAL > &Ratios)
void Fill(const T &copy, const int64_t from=0, const int64_t numelem=-1)
Will fill the elements of the vector with a copy object.
Definition: pzvec.h:460
int64_t Cols() const
Returns number of cols.
Definition: pzmatrix.h:809
int64_t NElements() const
Returns the number of elements of the vector.
Definition: pzvec.h:190
REAL fTol
Tolerance to project the coefficients to zero value.
REAL ZeroTolerance()
Returns the tolerance to Zero value. Actually: .
Definition: pzreal.h:633
int PutVal(const int64_t row, const int64_t col, const TVar &value) override
Put values without bounds checking This method is faster than "Put" if DEBUG is defined.
Definition: pzfmatrix.h:548
const TVar & GetVal(const int64_t row, const int64_t col) const override
Get values without bounds checking This method is faster than "Get" if DEBUG is defined.
Definition: pzfmatrix.h:566
void Transpose(TPZMatrix< TVar > *const T) const override
It makes *T the transpose of current matrix.
Definition: pzfmatrix.cpp:1073
virtual int SolveDirect(TPZFMatrix< TVar > &F, const DecomposeType dt, std::list< int64_t > &singular)
Solves the linear system using Direct methods.
Definition: pzmatrix.cpp:710
bool LeastSquaresToGetSimpleEllipse()
bool LeastSquaresToGetVerySimpleEllipse()