⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 peigen.cpp

📁 用于GPU通用计算的编程语言BrookGPU 0.4
💻 CPP
字号:
/*    Copyright (C) 1998 by Jorrit Tyberghein      This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.      This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Library General Public License for more details.      You should have received a copy of the GNU Library General Public    License along with this library; if not, write to the Free    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <math.h>#include "cs_compat.h"#include "qint.h"#include "csgeom/matrix3.h"//---------------------------------------------------------------------------#define rotate(a1,a2) g=a1; h=a2; a1=g-s*(h+g*tau); a2=h+s*(g-h*tau);#define swap(a,b)     { float t = a; a = b; b = t; }// M is the matrix for which we seek to find the eigen values.// vout is the matrix of eigen vectors.// dout is the vector of dominant eigen values.// returns:  -1   - error failed to converge within 50 iterations.//           0-50 - number of iterations.int Eigen (csMatrix3& M, csMatrix3& vout, csVector3& dout){  int i;  float tresh,theta,tau,t,sm,s,h,g,c;  int nrot;  csMatrix3 v;  csVector3 z (0, 0, 0);  // Load b and d with the diagonals of a.  csVector3 b (M.m11, M.m22, M.m33), d (M.m11, M.m22, M.m33);  nrot = 0;    // Try up to 50 times.  for(i=0; i<50; i++)    {      // See if bottom half of matrix a is non zero.      sm=0.0; sm+=ABS (M.m12); sm+=ABS (M.m13); sm+=ABS (M.m23);      // If it is 0 we are done.  Return the current vector v and d.      if (sm == 0.0)	{	  vout = v;	  dout = d;	  return i;	}            if (i < 3) tresh=0.2f*sm/(3*3); else tresh=0.0;            // Try rotations in 1st dimension      {	g = 100.0f*ABS (M.m12);  	// Does this make sense??	// equiv to   if (i>3 && g == 0) 	if (i>3 && ABS (d.x)+g==ABS (d.x) && ABS (d.y)+g==ABS (d.y))	  M.m12 =0.0f;	else if (ABS (M.m12)>tresh)	  {	    h = d.y-d.x;	    if (ABS (h)+g == ABS (h)) t=(M.m12)/h;	    else	      {		theta=0.5f*h/(M.m12);		t=1.0f/(ABS (theta)+sqrt(1.0f+theta*theta));		if (theta < 0.0) t = -t;	      }	    c=1.0f/sqrt(1+t*t); s=t*c; tau=s/(1.0f+c); h=t*M.m12;	    z.x -= h; z.y += h; d.x -= h; d.y += h;	    M.m12=0.0f;	    rotate(M.m13,M.m23); rotate(v.m11,v.m12);            rotate(v.m21,v.m22); rotate(v.m31,v.m32); 	    nrot++;	  }      }      // Try rotations in the 2nd dimension.      {	g = 100.0f*ABS (M.m13);	// See above, can be simplified.	if (i>3 && ABS (d.x)+g==ABS (d.x) && ABS (d.z)+g==ABS (d.z))	  M.m13=0.0f;	else if (ABS (M.m13)>tresh)	  {	    h = d.z-d.x;	    if (ABS (h)+g == ABS (h)) t=(M.m13)/h;	    else	      {		theta=0.5f*h/(M.m13);		t=1.0f/(ABS (theta)+sqrt(1.0f+theta*theta));		if (theta < 0.0f) t = -t;	      }	    c=1.0f/sqrt(1+t*t); s=t*c; tau=s/(1.0f+c); h=t*M.m13;	    z.x -= h; z.z += h; d.x -= h; d.z += h;	    M.m13=0.0f;	    rotate(M.m12,M.m23); rotate(v.m11,v.m13);            rotate(v.m21,v.m23); rotate(v.m31,v.m33); 	    nrot++;	  }      }      // Try rotations in 3rd dimension.      {	g = 100.0f*ABS (M.m23);	if (i>3 && ABS (d.y)+g==ABS (d.y) && ABS (d.z)+g==ABS (d.z))	  M.m23=0.0f;	else if (ABS (M.m23)>tresh)	  {	    h = d.z-d.y;	    if (ABS (h)+g == ABS (h)) t=(M.m23)/h;	    else	      {		theta=0.5f*h/(M.m23);		t=1.0f/(ABS (theta)+sqrt(1.0f+theta*theta));		if (theta < 0.0f) t = -t;	      }	    c=1.0f/sqrt(1+t*t); s=t*c; tau=s/(1.0f+c); h=t*M.m23;	    z.y -= h; z.z += h; d.y -= h; d.z += h;	    M.m23=0.0;	    rotate(M.m12,M.m13); rotate(v.m12,v.m13);            rotate(v.m22,v.m23); rotate(v.m32,v.m33); 	    nrot++;	  }      }      b = b + z; d = b; z.Set( 0, 0, 0);          }  return -1;}// Find eigen vectors of matrix M and sort them to have the largest// eigen vector in the first column.int SortedEigen (csMatrix3& M, csMatrix3& evecs){  int n;  csVector3 evals (0, 0, 0);  n = Eigen (M, evecs, evals);  if (evals.z > evals.x)    {      if (evals.z > evals.y)	{	  // 3 is largest, swap with column 1	  swap(evecs.m13,evecs.m11);	  swap(evecs.m23,evecs.m21);	  swap(evecs.m33,evecs.m31);	}      else	{	  // 2 is largest, swap with column 1	  swap(evecs.m12,evecs.m11);	  swap(evecs.m22,evecs.m21);	  swap(evecs.m32,evecs.m31);	}    }  else    {      if (evals.x > evals.y)	{	  // 1 is largest, do nothing	}      else	{  	  // 2 is largest	  swap(evecs.m12,evecs.m11);	  swap(evecs.m22,evecs.m21);	  swap(evecs.m32,evecs.m31);	}    }  // we are returning the number of iterations Meigen took.  // too many iterations means our chosen orientation is bad.  return n; }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -