]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake2/qdata_heretic2/svdcmp.c
eol style
[xonotic/netradiant.git] / tools / quake2 / qdata_heretic2 / svdcmp.c
index 8e02f8e49fd5105e422f23986dfb624634f4a8fa..e4496a19d77bed4a27e4b765b9d12498759c92df 100644 (file)
-/*\r
-Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
-For a list of contributors, see the accompanying CONTRIBUTORS file.\r
-\r
-This file is part of GtkRadiant.\r
-\r
-GtkRadiant is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-GtkRadiant is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with GtkRadiant; if not, write to the Free Software\r
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
-*/\r
-\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <assert.h>\r
-#include <string.h>\r
-#include <math.h>\r
-\r
-static double at,bt,ct;\r
-#define PYTHAG(a,b) ((at=fabs(a)) > (bt=fabs(b)) ? \\r
-                    (ct=bt/at,at*sqrt(1.0+ct*ct)) : (bt ? (ct=at/bt,bt*sqrt(1.0+ct*ct)): 0.0))\r
-\r
-  static double maxarg1,maxarg2;\r
-#define MAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ?\\r
-                 (maxarg1) : (maxarg2))\r
-#define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))\r
-\r
-void ntrerror(char *s)\r
-{\r
-  printf("%s\n",s);\r
-  exit(1);\r
-}\r
-\r
-double *allocVect(int sz)\r
-{\r
-       double *ret;\r
-       \r
-       ret = calloc(sizeof(double), (size_t)sz);\r
-       return ret;\r
-}\r
-\r
-void freeVect(double *ret)\r
-{\r
-       free(ret);\r
-}\r
-\r
-double **allocMatrix(int r,int c)\r
-{\r
-       double **ret;\r
-               \r
-       ret = calloc(sizeof(double), (size_t)(r*c));\r
-       return ret;\r
-}\r
-\r
-void freeMatrix(double **ret,int r)\r
-{\r
-       free(ret);\r
-}\r
-\r
-void svdcmp(double** a, int m, int n, double* w, double** v)\r
-{\r
-  int flag,i,its,j,jj,k,l,nm;\r
-  double c,f,h,s,x,y,z;\r
-  double anorm=0.0,g=0.0,scale=0.0;\r
-  double *rv1;\r
-  void nrerror();\r
-\r
-  if (m < n) ntrerror("SVDCMP: You must augment A with extra zero rows");\r
-  rv1=allocVect(n);\r
-  for (i=1;i<=n;i++) {\r
-    l=i+1;\r
-    rv1[i]=scale*g;\r
-    g=s=scale=0.0;\r
-    if (i <= m) {\r
-      for (k=i;k<=m;k++) scale += fabs(a[k][i]);\r
-      if (scale) {\r
-       for (k=i;k<=m;k++) {\r
-         a[k][i] /= scale;\r
-         s += a[k][i]*a[k][i];\r
-       }\r
-       f=a[i][i];\r
-       g = -SIGN(sqrt(s),f);\r
-       h=f*g-s;\r
-       a[i][i]=f-g;\r
-       if (i != n) {\r
-         for (j=l;j<=n;j++) {\r
-           for (s=0.0,k=i;k<=m;k++) s += a[k][i]*a[k][j];\r
-           f=s/h;\r
-           for (k=i;k<=m;k++) a[k][j] += f*a[k][i];\r
-         }\r
-       }\r
-       for (k=i;k<=m;k++) a[k][i] *= scale;\r
-      }\r
-    }\r
-    w[i]=scale*g;\r
-    g=s=scale=0.0;\r
-    if (i <= m && i != n) {\r
-      for (k=l;k<=n;k++) scale += fabs(a[i][k]);\r
-      if (scale) {\r
-       for (k=l;k<=n;k++) {\r
-         a[i][k] /= scale;\r
-         s += a[i][k]*a[i][k];\r
-       }\r
-       f=a[i][l];\r
-       g = -SIGN(sqrt(s),f);\r
-       h=f*g-s;\r
-       a[i][l]=f-g;\r
-       for (k=l;k<=n;k++) rv1[k]=a[i][k]/h;\r
-       if (i != m) {\r
-         for (j=l;j<=m;j++) {\r
-           for (s=0.0,k=l;k<=n;k++) s += a[j][k]*a[i][k];\r
-           for (k=l;k<=n;k++) a[j][k] += s*rv1[k];\r
-         }\r
-       }\r
-       for (k=l;k<=n;k++) a[i][k] *= scale;\r
-      }\r
-    }\r
-    anorm=MAX(anorm,(fabs(w[i])+fabs(rv1[i])));\r
-  }\r
-  for (i=n;i>=1;i--) {\r
-    if (i < n) {\r
-      if (g) {\r
-       for (j=l;j<=n;j++)\r
-         v[j][i]=(a[i][j]/a[i][l])/g;\r
-       for (j=l;j<=n;j++) {\r
-         for (s=0.0,k=l;k<=n;k++) s += a[i][k]*v[k][j];\r
-         for (k=l;k<=n;k++) v[k][j] += s*v[k][i];\r
-       }\r
-      }\r
-      for (j=l;j<=n;j++) v[i][j]=v[j][i]=0.0;\r
-    }\r
-    v[i][i]=1.0;\r
-    g=rv1[i];\r
-    l=i;\r
-  }\r
-  for (i=n;i>=1;i--) {\r
-    l=i+1;\r
-    g=w[i];\r
-    if (i < n)\r
-      for (j=l;j<=n;j++) a[i][j]=0.0;\r
-    if (g) {\r
-      g=1.0/g;\r
-      if (i != n) {\r
-       for (j=l;j<=n;j++) {\r
-         for (s=0.0,k=l;k<=m;k++) s += a[k][i]*a[k][j];\r
-         f=(s/a[i][i])*g;\r
-         for (k=i;k<=m;k++) a[k][j] += f*a[k][i];\r
-       }\r
-      }\r
-      for (j=i;j<=m;j++) a[j][i] *= g;\r
-    } else {\r
-      for (j=i;j<=m;j++) a[j][i]=0.0;\r
-    }\r
-    ++a[i][i];\r
-  }\r
-  for (k=n;k>=1;k--) {\r
-    for (its=1;its<=30;its++) {\r
-      flag=1;\r
-      for (l=k;l>=1;l--) {\r
-       nm=l-1;\r
-       if (fabs(rv1[l])+anorm == anorm) {\r
-         flag=0;\r
-         break;\r
-       }\r
-       if (fabs(w[nm])+anorm == anorm) break;\r
-      }\r
-      if (flag) {\r
-       c=0.0;\r
-       s=1.0;\r
-       for (i=l;i<=k;i++) {\r
-         f=s*rv1[i];\r
-         if (fabs(f)+anorm != anorm) {\r
-           g=w[i];\r
-           h=PYTHAG(f,g);\r
-           w[i]=h;\r
-           h=1.0/h;\r
-           c=g*h;\r
-           s=(-f*h);\r
-           for (j=1;j<=m;j++) {\r
-             y=a[j][nm];\r
-             z=a[j][i];\r
-             a[j][nm]=y*c+z*s;\r
-             a[j][i]=z*c-y*s;\r
-           }\r
-         }\r
-       }\r
-      }\r
-      z=w[k];\r
-      if (l == k) {\r
-       if (z < 0.0) {\r
-         w[k] = -z;\r
-         for (j=1;j<=n;j++) v[j][k]=(-v[j][k]);\r
-       }\r
-       break;\r
-      }\r
-      if (its == 30) ntrerror("No convergence in 30 SVDCMP iterations");\r
-      x=w[l];\r
-      nm=k-1;\r
-      y=w[nm];\r
-      g=rv1[nm];\r
-      h=rv1[k];\r
-      f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y);\r
-      g=PYTHAG(f,1.0);\r
-      f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x;\r
-      c=s=1.0;\r
-      for (j=l;j<=nm;j++) {\r
-       i=j+1;\r
-       g=rv1[i];\r
-       y=w[i];\r
-       h=s*g;\r
-       g=c*g;\r
-       z=PYTHAG(f,h);\r
-       rv1[j]=z;\r
-       c=f/z;\r
-       s=h/z;\r
-       f=x*c+g*s;\r
-       g=g*c-x*s;\r
-       h=y*s;\r
-       y=y*c;\r
-       for (jj=1;jj<=n;jj++) {\r
-         x=v[jj][j];\r
-         z=v[jj][i];\r
-         v[jj][j]=x*c+z*s;\r
-         v[jj][i]=z*c-x*s;\r
-       }\r
-       z=PYTHAG(f,h);\r
-       w[j]=z;\r
-       if (z) {\r
-         z=1.0/z;\r
-         c=f*z;\r
-         s=h*z;\r
-       }\r
-       f=(c*g)+(s*y);\r
-       x=(c*y)-(s*g);\r
-       for (jj=1;jj<=m;jj++) {\r
-         y=a[jj][j];\r
-         z=a[jj][i];\r
-         a[jj][j]=y*c+z*s;\r
-         a[jj][i]=z*c-y*s;\r
-       }\r
-      }\r
-      rv1[l]=0.0;\r
-      rv1[k]=f;\r
-      w[k]=x;\r
-    }\r
-  }\r
-  freeVect(rv1);\r
-}\r
-\r
-\r
-\r
-void svbksb(double** u, double* w, double** v,int m, int n, double* b, double* x)\r
-{  \r
-       int jj,j,i; \r
-       double s,*tmp;\r
-       tmp=allocVect(n);\r
-       for (j=1;j<=n;j++) \r
-       {    \r
-               s=0.0;    \r
-               if (w[j]) \r
-               {\r
-                       for (i=1;i<=m;i++) \r
-                               s += u[i][j]*b[i];   \r
-                       s /= w[j];   \r
-               }   \r
-               tmp[j]=s; \r
-       }\r
-       for (j=1;j<=n;j++) \r
-       {   \r
-               s=0.0;  \r
-               for (jj=1;jj<=n;jj++) \r
-                       s += v[j][jj]*tmp[jj];\r
-               x[j]=s;\r
-       } \r
-       freeVect(tmp);\r
-}\r
-\r
-#undef SIGN\r
-#undef MAX\r
-#undef PYTHAG\r
-\r
-\r
-#if 1\r
-void DOsvd(float *a,float *res,float *comp,float *values,int nframes,int framesize,int compressedsize)\r
-{\r
-       int usedfs;\r
-       int *remap;\r
-       int i,j;\r
-       double **da;\r
-       double **v;\r
-       double *w;\r
-       int DOFerr;\r
-       float mx;\r
-       int bestat;\r
-\r
-       if (nframes>framesize)\r
-               usedfs=nframes;\r
-       else\r
-               usedfs=framesize;\r
-\r
-       da=allocMatrix(usedfs,nframes);\r
-       v=allocMatrix(nframes,nframes);\r
-       w=allocVect(nframes);\r
-\r
-       DOFerr = 0; //false\r
-       for (i=0;i<nframes;i++)\r
-       {\r
-               for (j=0;j<framesize;j++)\r
-                       da[j+1][i+1]=a[i*framesize+j];\r
-               for (;j<usedfs;j++)\r
-                       da[j+1][i+1]=0.0;\r
-       }\r
-\r
-       svdcmp(da,usedfs,nframes,w,v);\r
-\r
-       remap = calloc(sizeof(int), (size_t)nframes);\r
-\r
-\r
-       for (i=0;i<nframes;i++)\r
-               remap[i]=-1;\r
-       for (j=0;j<compressedsize;j++)\r
-       {\r
-               mx=-1.0f;\r
-               for (i=0;i<nframes;i++)\r
-               {\r
-                       if (remap[i]<0&&fabs(w[i+1])>mx)\r
-                       {\r
-                               mx=(float) fabs(w[i+1]);\r
-                               bestat=i;\r
-                       }\r
-               }\r
-\r
-               if(mx>0)\r
-               {\r
-                       remap[bestat]=j;\r
-               }\r
-               else\r
-               {\r
-                       DOFerr = 1; //true\r
-               }\r
-       }\r
-\r
-       if(DOFerr)\r
-       {\r
-               printf("Warning:  To many degrees of freedom!  File size may increase\n");\r
-\r
-               for (i=0;i<compressedsize;i++)\r
-               {\r
-                       values[i]=0;\r
-                       for (j=0;j<framesize;j++)\r
-                               res[i*framesize+j]=0;\r
-               }\r
-       }\r
-\r
-       for (i=0;i<nframes;i++)\r
-       {\r
-               if (remap[i]<0)\r
-                       w[i+1]=0.0;\r
-               else\r
-               {\r
-                       values[remap[i]]=(float) w[i+1];\r
-                       for (j=0;j<framesize;j++)\r
-                               res[remap[i]*framesize+j]=(float) da[j+1][i+1];\r
-               }\r
-       }\r
-       freeVect(w);\r
-       freeMatrix(v,nframes);\r
-       freeMatrix(da,framesize);\r
-       free(remap);\r
-}\r
-\r
-#else\r
-\r
-void DOsvd(float *a,float *res,float *comp,float *values,int nframes,int framesize,int compressedsize)\r
-{\r
-       int *remap;\r
-       int i,j;\r
-       int nrows;\r
-       nrows=nframes;\r
-       if (nrows<framesize)\r
-               nrows=framesize;\r
-       double **da=allocMatrix(nrows,framesize);\r
-       double **v=allocMatrix(framesize,framesize);\r
-       double *w=allocVect(framesize);\r
-       float mx;\r
-       int bestat;\r
-\r
-       for (j=0;j<framesize;j++)\r
-       {\r
-               for (i=0;i<nframes;i++)\r
-                       da[j+1][i+1]=a[i*framesize+j];\r
-               for (;i<nrows;i++)\r
-                       da[j+1][i+1]=0.0;\r
-       }\r
-\r
-       svdcmp(da,nrows,framesize,w,v);\r
-\r
-       remap=new int[framesize];\r
-\r
-\r
-       for (i=0;i<framesize;i++)\r
-               remap[i]=-1;\r
-       for (j=0;j<compressedsize;j++)\r
-       {\r
-               mx=-1.0f;\r
-               for (i=0;i<framesize;i++)\r
-               {\r
-                       if (remap[i]<0&&fabs(w[i+1])>mx)\r
-                       {\r
-                               mx=fabs(w[i+1]);\r
-                               bestat=i;\r
-                       }\r
-               }\r
-               assert(mx>-.5f);\r
-               remap[bestat]=j;\r
-       }\r
-       // josh **DO NOT** put your dof>nframes mod here\r
-       for (i=0;i<framesize;i++)\r
-       {\r
-               if (remap[i]<0)\r
-                       w[i+1]=0.0;\r
-               else\r
-               {\r
-                       values[remap[i]]=w[i+1];\r
-                       for (j=0;j<framesize;j++)\r
-                               res[remap[i]*framesize+j]=v[j+1][i+1];\r
-               }\r
-       }\r
-       freeVect(w);\r
-       freeMatrix(v,framesize);\r
-       freeMatrix(da,nrows);\r
-       delete[] remap;\r
-}\r
-\r
-#endif\r
-\r
-void DOsvdPlane(float *pnts,int npnts,float *n,float *base)\r
-{\r
-       int i,j;\r
-       double **da=allocMatrix(npnts,3);\r
-       double **v=allocMatrix(3,3);\r
-       double *w=allocVect(3);\r
-       float mn=1E30f;\r
-       int bestat;\r
-\r
-\r
-       assert(npnts>=3);\r
-       base[0]=pnts[0];\r
-       base[1]=pnts[1];\r
-       base[2]=pnts[2];\r
-       for (i=1;i<npnts;i++)\r
-       {\r
-               for (j=0;j<3;j++)\r
-                       base[j]+=pnts[i*3+j];\r
-       }\r
-       base[0]/=(float)(npnts);\r
-       base[1]/=(float)(npnts);\r
-       base[2]/=(float)(npnts);\r
-\r
-       for (i=0;i<3;i++)\r
-       {\r
-               for (j=0;j<npnts;j++)\r
-                       da[j+1][i+1]=pnts[j*3+i]-base[i];\r
-       }\r
-\r
-       svdcmp(da,npnts,3,w,v);\r
-       for (i=0;i<3;i++)\r
-       {\r
-               if (fabs(w[i+1])<mn)\r
-               {\r
-                       mn=(float) fabs(w[i+1]);\r
-                       bestat=i;\r
-               }\r
-       }\r
-       n[0]=(float) v[1][bestat+1];\r
-       n[1]=(float) v[2][bestat+1];\r
-       n[2]=(float) v[3][bestat+1];\r
-       freeVect(w);\r
-       freeMatrix(v,3);\r
-       freeMatrix(da,npnts);\r
-}\r
+/*
+Copyright (C) 1999-2007 id Software, Inc. and contributors.
+For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+This file is part of GtkRadiant.
+
+GtkRadiant is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GtkRadiant 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GtkRadiant; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+
+static double at,bt,ct;
+#define PYTHAG(a,b) ((at=fabs(a)) > (bt=fabs(b)) ? \
+                    (ct=bt/at,at*sqrt(1.0+ct*ct)) : (bt ? (ct=at/bt,bt*sqrt(1.0+ct*ct)): 0.0))
+
+  static double maxarg1,maxarg2;
+#define MAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ?\
+                 (maxarg1) : (maxarg2))
+#define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
+
+void ntrerror(char *s)
+{
+  printf("%s\n",s);
+  exit(1);
+}
+
+double *allocVect(int sz)
+{
+       double *ret;
+       
+       ret = calloc(sizeof(double), (size_t)sz);
+       return ret;
+}
+
+void freeVect(double *ret)
+{
+       free(ret);
+}
+
+double **allocMatrix(int r,int c)
+{
+       double **ret;
+               
+       ret = calloc(sizeof(double), (size_t)(r*c));
+       return ret;
+}
+
+void freeMatrix(double **ret,int r)
+{
+       free(ret);
+}
+
+void svdcmp(double** a, int m, int n, double* w, double** v)
+{
+  int flag,i,its,j,jj,k,l,nm;
+  double c,f,h,s,x,y,z;
+  double anorm=0.0,g=0.0,scale=0.0;
+  double *rv1;
+  void nrerror();
+
+  if (m < n) ntrerror("SVDCMP: You must augment A with extra zero rows");
+  rv1=allocVect(n);
+  for (i=1;i<=n;i++) {
+    l=i+1;
+    rv1[i]=scale*g;
+    g=s=scale=0.0;
+    if (i <= m) {
+      for (k=i;k<=m;k++) scale += fabs(a[k][i]);
+      if (scale) {
+       for (k=i;k<=m;k++) {
+         a[k][i] /= scale;
+         s += a[k][i]*a[k][i];
+       }
+       f=a[i][i];
+       g = -SIGN(sqrt(s),f);
+       h=f*g-s;
+       a[i][i]=f-g;
+       if (i != n) {
+         for (j=l;j<=n;j++) {
+           for (s=0.0,k=i;k<=m;k++) s += a[k][i]*a[k][j];
+           f=s/h;
+           for (k=i;k<=m;k++) a[k][j] += f*a[k][i];
+         }
+       }
+       for (k=i;k<=m;k++) a[k][i] *= scale;
+      }
+    }
+    w[i]=scale*g;
+    g=s=scale=0.0;
+    if (i <= m && i != n) {
+      for (k=l;k<=n;k++) scale += fabs(a[i][k]);
+      if (scale) {
+       for (k=l;k<=n;k++) {
+         a[i][k] /= scale;
+         s += a[i][k]*a[i][k];
+       }
+       f=a[i][l];
+       g = -SIGN(sqrt(s),f);
+       h=f*g-s;
+       a[i][l]=f-g;
+       for (k=l;k<=n;k++) rv1[k]=a[i][k]/h;
+       if (i != m) {
+         for (j=l;j<=m;j++) {
+           for (s=0.0,k=l;k<=n;k++) s += a[j][k]*a[i][k];
+           for (k=l;k<=n;k++) a[j][k] += s*rv1[k];
+         }
+       }
+       for (k=l;k<=n;k++) a[i][k] *= scale;
+      }
+    }
+    anorm=MAX(anorm,(fabs(w[i])+fabs(rv1[i])));
+  }
+  for (i=n;i>=1;i--) {
+    if (i < n) {
+      if (g) {
+       for (j=l;j<=n;j++)
+         v[j][i]=(a[i][j]/a[i][l])/g;
+       for (j=l;j<=n;j++) {
+         for (s=0.0,k=l;k<=n;k++) s += a[i][k]*v[k][j];
+         for (k=l;k<=n;k++) v[k][j] += s*v[k][i];
+       }
+      }
+      for (j=l;j<=n;j++) v[i][j]=v[j][i]=0.0;
+    }
+    v[i][i]=1.0;
+    g=rv1[i];
+    l=i;
+  }
+  for (i=n;i>=1;i--) {
+    l=i+1;
+    g=w[i];
+    if (i < n)
+      for (j=l;j<=n;j++) a[i][j]=0.0;
+    if (g) {
+      g=1.0/g;
+      if (i != n) {
+       for (j=l;j<=n;j++) {
+         for (s=0.0,k=l;k<=m;k++) s += a[k][i]*a[k][j];
+         f=(s/a[i][i])*g;
+         for (k=i;k<=m;k++) a[k][j] += f*a[k][i];
+       }
+      }
+      for (j=i;j<=m;j++) a[j][i] *= g;
+    } else {
+      for (j=i;j<=m;j++) a[j][i]=0.0;
+    }
+    ++a[i][i];
+  }
+  for (k=n;k>=1;k--) {
+    for (its=1;its<=30;its++) {
+      flag=1;
+      for (l=k;l>=1;l--) {
+       nm=l-1;
+       if (fabs(rv1[l])+anorm == anorm) {
+         flag=0;
+         break;
+       }
+       if (fabs(w[nm])+anorm == anorm) break;
+      }
+      if (flag) {
+       c=0.0;
+       s=1.0;
+       for (i=l;i<=k;i++) {
+         f=s*rv1[i];
+         if (fabs(f)+anorm != anorm) {
+           g=w[i];
+           h=PYTHAG(f,g);
+           w[i]=h;
+           h=1.0/h;
+           c=g*h;
+           s=(-f*h);
+           for (j=1;j<=m;j++) {
+             y=a[j][nm];
+             z=a[j][i];
+             a[j][nm]=y*c+z*s;
+             a[j][i]=z*c-y*s;
+           }
+         }
+       }
+      }
+      z=w[k];
+      if (l == k) {
+       if (z < 0.0) {
+         w[k] = -z;
+         for (j=1;j<=n;j++) v[j][k]=(-v[j][k]);
+       }
+       break;
+      }
+      if (its == 30) ntrerror("No convergence in 30 SVDCMP iterations");
+      x=w[l];
+      nm=k-1;
+      y=w[nm];
+      g=rv1[nm];
+      h=rv1[k];
+      f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y);
+      g=PYTHAG(f,1.0);
+      f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x;
+      c=s=1.0;
+      for (j=l;j<=nm;j++) {
+       i=j+1;
+       g=rv1[i];
+       y=w[i];
+       h=s*g;
+       g=c*g;
+       z=PYTHAG(f,h);
+       rv1[j]=z;
+       c=f/z;
+       s=h/z;
+       f=x*c+g*s;
+       g=g*c-x*s;
+       h=y*s;
+       y=y*c;
+       for (jj=1;jj<=n;jj++) {
+         x=v[jj][j];
+         z=v[jj][i];
+         v[jj][j]=x*c+z*s;
+         v[jj][i]=z*c-x*s;
+       }
+       z=PYTHAG(f,h);
+       w[j]=z;
+       if (z) {
+         z=1.0/z;
+         c=f*z;
+         s=h*z;
+       }
+       f=(c*g)+(s*y);
+       x=(c*y)-(s*g);
+       for (jj=1;jj<=m;jj++) {
+         y=a[jj][j];
+         z=a[jj][i];
+         a[jj][j]=y*c+z*s;
+         a[jj][i]=z*c-y*s;
+       }
+      }
+      rv1[l]=0.0;
+      rv1[k]=f;
+      w[k]=x;
+    }
+  }
+  freeVect(rv1);
+}
+
+
+
+void svbksb(double** u, double* w, double** v,int m, int n, double* b, double* x)
+{  
+       int jj,j,i; 
+       double s,*tmp;
+       tmp=allocVect(n);
+       for (j=1;j<=n;j++) 
+       {    
+               s=0.0;    
+               if (w[j]) 
+               {
+                       for (i=1;i<=m;i++) 
+                               s += u[i][j]*b[i];   
+                       s /= w[j];   
+               }   
+               tmp[j]=s; 
+       }
+       for (j=1;j<=n;j++) 
+       {   
+               s=0.0;  
+               for (jj=1;jj<=n;jj++) 
+                       s += v[j][jj]*tmp[jj];
+               x[j]=s;
+       } 
+       freeVect(tmp);
+}
+
+#undef SIGN
+#undef MAX
+#undef PYTHAG
+
+
+#if 1
+void DOsvd(float *a,float *res,float *comp,float *values,int nframes,int framesize,int compressedsize)
+{
+       int usedfs;
+       int *remap;
+       int i,j;
+       double **da;
+       double **v;
+       double *w;
+       int DOFerr;
+       float mx;
+       int bestat;
+
+       if (nframes>framesize)
+               usedfs=nframes;
+       else
+               usedfs=framesize;
+
+       da=allocMatrix(usedfs,nframes);
+       v=allocMatrix(nframes,nframes);
+       w=allocVect(nframes);
+
+       DOFerr = 0; //false
+       for (i=0;i<nframes;i++)
+       {
+               for (j=0;j<framesize;j++)
+                       da[j+1][i+1]=a[i*framesize+j];
+               for (;j<usedfs;j++)
+                       da[j+1][i+1]=0.0;
+       }
+
+       svdcmp(da,usedfs,nframes,w,v);
+
+       remap = calloc(sizeof(int), (size_t)nframes);
+
+
+       for (i=0;i<nframes;i++)
+               remap[i]=-1;
+       for (j=0;j<compressedsize;j++)
+       {
+               mx=-1.0f;
+               for (i=0;i<nframes;i++)
+               {
+                       if (remap[i]<0&&fabs(w[i+1])>mx)
+                       {
+                               mx=(float) fabs(w[i+1]);
+                               bestat=i;
+                       }
+               }
+
+               if(mx>0)
+               {
+                       remap[bestat]=j;
+               }
+               else
+               {
+                       DOFerr = 1; //true
+               }
+       }
+
+       if(DOFerr)
+       {
+               printf("Warning:  To many degrees of freedom!  File size may increase\n");
+
+               for (i=0;i<compressedsize;i++)
+               {
+                       values[i]=0;
+                       for (j=0;j<framesize;j++)
+                               res[i*framesize+j]=0;
+               }
+       }
+
+       for (i=0;i<nframes;i++)
+       {
+               if (remap[i]<0)
+                       w[i+1]=0.0;
+               else
+               {
+                       values[remap[i]]=(float) w[i+1];
+                       for (j=0;j<framesize;j++)
+                               res[remap[i]*framesize+j]=(float) da[j+1][i+1];
+               }
+       }
+       freeVect(w);
+       freeMatrix(v,nframes);
+       freeMatrix(da,framesize);
+       free(remap);
+}
+
+#else
+
+void DOsvd(float *a,float *res,float *comp,float *values,int nframes,int framesize,int compressedsize)
+{
+       int *remap;
+       int i,j;
+       int nrows;
+       nrows=nframes;
+       if (nrows<framesize)
+               nrows=framesize;
+       double **da=allocMatrix(nrows,framesize);
+       double **v=allocMatrix(framesize,framesize);
+       double *w=allocVect(framesize);
+       float mx;
+       int bestat;
+
+       for (j=0;j<framesize;j++)
+       {
+               for (i=0;i<nframes;i++)
+                       da[j+1][i+1]=a[i*framesize+j];
+               for (;i<nrows;i++)
+                       da[j+1][i+1]=0.0;
+       }
+
+       svdcmp(da,nrows,framesize,w,v);
+
+       remap=new int[framesize];
+
+
+       for (i=0;i<framesize;i++)
+               remap[i]=-1;
+       for (j=0;j<compressedsize;j++)
+       {
+               mx=-1.0f;
+               for (i=0;i<framesize;i++)
+               {
+                       if (remap[i]<0&&fabs(w[i+1])>mx)
+                       {
+                               mx=fabs(w[i+1]);
+                               bestat=i;
+                       }
+               }
+               assert(mx>-.5f);
+               remap[bestat]=j;
+       }
+       // josh **DO NOT** put your dof>nframes mod here
+       for (i=0;i<framesize;i++)
+       {
+               if (remap[i]<0)
+                       w[i+1]=0.0;
+               else
+               {
+                       values[remap[i]]=w[i+1];
+                       for (j=0;j<framesize;j++)
+                               res[remap[i]*framesize+j]=v[j+1][i+1];
+               }
+       }
+       freeVect(w);
+       freeMatrix(v,framesize);
+       freeMatrix(da,nrows);
+       delete[] remap;
+}
+
+#endif
+
+void DOsvdPlane(float *pnts,int npnts,float *n,float *base)
+{
+       int i,j;
+       double **da=allocMatrix(npnts,3);
+       double **v=allocMatrix(3,3);
+       double *w=allocVect(3);
+       float mn=1E30f;
+       int bestat;
+
+
+       assert(npnts>=3);
+       base[0]=pnts[0];
+       base[1]=pnts[1];
+       base[2]=pnts[2];
+       for (i=1;i<npnts;i++)
+       {
+               for (j=0;j<3;j++)
+                       base[j]+=pnts[i*3+j];
+       }
+       base[0]/=(float)(npnts);
+       base[1]/=(float)(npnts);
+       base[2]/=(float)(npnts);
+
+       for (i=0;i<3;i++)
+       {
+               for (j=0;j<npnts;j++)
+                       da[j+1][i+1]=pnts[j*3+i]-base[i];
+       }
+
+       svdcmp(da,npnts,3,w,v);
+       for (i=0;i<3;i++)
+       {
+               if (fabs(w[i+1])<mn)
+               {
+                       mn=(float) fabs(w[i+1]);
+                       bestat=i;
+               }
+       }
+       n[0]=(float) v[1][bestat+1];
+       n[1]=(float) v[2][bestat+1];
+       n[2]=(float) v[3][bestat+1];
+       freeVect(w);
+       freeMatrix(v,3);
+       freeMatrix(da,npnts);
+}