regress.C

Go to the documentation of this file.
00001 /* Gxsm - Gnome X Scanning Microscopy
00002  * universal STM/AFM/SARLS/SPALEED/... controlling and
00003  * data analysis software
00004  * 
00005  * Copyright (C) 1999,2000,2001,2002,2003 Percy Zahl
00006  *
00007  * Authors: Percy Zahl <zahl@users.sf.net>
00008  * additional features: Andreas Klust <klust@users.sf.net>
00009  * WWW Home: http://gxsm.sf.net
00010  *
00011  * This program is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00024  */
00025 
00026 /* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 8 c-style: "K&R" -*- */
00027 
00028 /********************************************************
00029  *                                                      *
00030  *              REGRES.CPP :                            *
00031  *              Regression                              *
00032  *              Für Polynome nten Grades                *
00033  *              by Percy Zahl, Version 1.0, 18.2.1994   *
00034  *
00035  *
00036  *
00037  ********************************************************/
00038 
00039 #include <iostream>
00040 #include <fstream>
00041 
00042 #include <cmath>
00043 #include <cstdlib>
00044 #include <cstring>
00045 #include <cstdarg>
00046 #include <cstdio>
00047 
00048 #include "regress.h"
00049 
00050 // be verbose?
00051 // #define TALK
00052 
00053 double  gpow(double X, int n)
00054 {       double  px=1.;
00055         if(n > 0)
00056                 while(n--) px*=X;
00057         else
00058                 if(n < 0)
00059                         while(n++) px/=X;
00060         return px;
00061 }
00062 
00063 
00064 void StatInp::Optimize(){
00065         int     i,k,Nq;
00066         double  q, Vi;
00067         gs = new LGSys(PGrad);
00068         gs->Eingabe(this);
00069         gs->Ausgabe_Loesung(gs->DoIt());
00070 #ifdef TALK
00071         std::cout << "\n\nAusgleichspolynom:\n y(x) = ";
00072         for(i=0; i<PGrad; i++){
00073                 if(i==0)
00074                         std::cout << gs->GetPolyK(i);
00075                 else
00076                         std::cout << " + " << gs->GetPolyK(i) << " x";
00077                 if(i>1)
00078                         std::cout << "^" << i;
00079         }
00080         std::cout << "\n\nStatistische Parameter:\n";
00081         std::cout << "Anzahl Stichproben: N = " << N << "\n";
00082 #endif
00083         for(Vi=0., i=0; i<N; i++)
00084                 Vi += (q = (y[i] - gs->CalcPoly(x[i], -1)) )*q;
00085 #ifdef TALK
00086         std::cout << "Summe der Abweichungsquadrate / Anzahl = " << Vi/N << "\n\n";
00087 #endif
00088         for(k=0; k<PGrad; k++){
00089                 for(Nq=N, Vi=0., i=0; i<N; i++)
00090                         if(x[i] != 0.)
00091                                 Vi += (q = (gs->GetPolyK(k) - (y[i] - gs->CalcPoly(x[i], k))/gpow(x[i],k)) )*q;
00092                         else
00093                                 --Nq;
00094 #ifdef TALK
00095                 std::cout << "a[" << k << "]      = " << gs->GetPolyK(k) << "\n";
00096                 if(Nq-1 > 0) std::cout << "sig(N-1)[" << k << "] = " << sqrt(Vi/(double)(Nq-1)) << "\n";
00097                 else std::cout << "Zu wenig Werte !\n";
00098                 if(Nq > 0)      std::cout << "sig(N)[" << k << "]   = " << sqrt(Vi/(double)Nq) << "\n";
00099                 else std::cout << "Zu wenig Werte !\n";
00100 #endif
00101         }
00102 }
00103 
00104 Zeile::Zeile(int nk, int gm)
00105 {       int     i;
00106         n=nk; m=gm;
00107         gl = new double[n+1];
00108         for(i=0; i<=n; i++)     // Koeffizienten und b einlesen
00109         {       if(i<n) std::cout << "\nGL " << (m+1) << " : x" << (i+1) << " : ";
00110                 else    std::cout << "\nGL " << (m+1) << " : b  : ";
00111                 std::cin >> gl[i];
00112         }
00113 }
00114 
00115 Zeile::Zeile(int nk, int gm, StatInp *koef)
00116 {       int     i;
00117         n=nk; m=gm;
00118         gl = new double[n+1];
00119         for(i=0; i<=n; i++)     // Koeffizienten und b einlesen
00120                 gl[i]=koef->CalcKoef(i,m);
00121 }
00122 
00123 int Zeile::Test(int start)
00124 {       int     i;
00125         for(i=start; i<=n && gl[i]==0; i++);
00126         return(i);
00127 }
00128 
00129 void Zeile::Mult(double faktor)
00130 {       int     i;
00131         for(i=0; i<=n; i++) gl[i] *= faktor;
00132         for(i=0; i<=n; i++) if(fabs(gl[i]) < Delta) gl[i]=0.;
00133 }
00134 
00135 void Zeile::Add(class Zeile* z)
00136 {       int     i;
00137         for(i=0; i<=n; i++) gl[i] += z->gl[i];
00138 }
00139 
00140 void Zeile::P_Zeile()
00141 {       int i;
00142         for(i=0; i<n; i++)      // Koeffizienten und b ausgeben
00143         {
00144                 if(i==0) std::cout << "\nGL " << (m+1) << " : ";
00145                 std::cout << gl[i] << " x" << (i+1);
00146                 if(i<(n-1)) std::cout  << " + "; else std::cout << " = " << gl[i+1];
00147         }
00148 }
00149 
00150 void LGSys::Eingabe()
00151 {
00152         int     i;
00153         do{     
00154                 std::cout << "Eingabe des Linearen Gleichungssystems\n";
00155                 std::cout << "\n Anzahl  der  Variablen: ";
00156                 std::cin >> n;
00157                 std::cout << "\n Anzahl der Gleichungen: ";
00158                 std::cin >> m;
00159         } while((n>=MAXVAR)||(m>=MAXGL));
00160         std::cout << "\n Koeffizienten eingeben: ";
00161         for(i=0; i<m; i++)
00162         {       gln[i] = new Zeile(n,i); st_fkt[i]= -1; }
00163 }
00164 
00165 
00166 void LGSys::Eingabe(StatInp* StatObj)
00167 {
00168         int     i;
00169 #ifdef TALK
00170         std::cout << "Erstelle Gleichungssystem j=";
00171 #endif
00172         for(i=0; i<m; i++)
00173         {       
00174           gln[i] = new Zeile(n,i,StatObj); st_fkt[i]= -1;
00175 #ifdef TALK
00176           std::cout << i+1 << " "; 
00177 #endif
00178         }
00179 #ifdef TALK
00180         std::cout << "\n";
00181 #endif
00182 }
00183 
00184 void LGSys::Tausche(int i,int j)
00185 {
00186         class Zeile* x;
00187         if(i!=j) { x=gln[i]; gln[i]=gln[j]; gln[j]=x; }
00188 }
00189 
00190 int LGSys::SucheGl(int start)
00191 {
00192         int     i,j,k,l;
00193         for(k= -1, j=n+1, i=start; i<m && j>0; i++)
00194                 if((l=gln[i]->Test(start)) < j) { k=i; j=l; }
00195         if(k== -1) return(NEG);
00196         Tausche(start,k);
00197         return(st_fkt[start]=j);
00198 }
00199 
00200 int LGSys::Umformen()
00201 {
00202         int     i,j;
00203         for(i=0; i<m; i++)
00204         {   
00205 #ifdef TALK
00206                 Ausgabe_Glsys(); 
00207 //              std::cin; 
00208                 std::cout << "\nSchritt " << i+1 << " : "; 
00209 #endif
00210                 if(SucheGl(i)==NEG) break; // Fertig
00211                 if(i >= (m-1)) { i++; break; }
00212                 for(j=i+1; j<m; j++)
00213                 {       if(gln[j]->Wert(st_fkt[i])==0.) continue;
00214                         gln[j]->Mult(-(gln[i]->Wert(st_fkt[i])/gln[j]->Wert(st_fkt[i])));
00215                         gln[j]->Add(gln[i]);
00216                 }
00217         }
00218 #ifdef TALK
00219         Ausgabe_Glsys();
00220         std::cout << "\nRang der erweiterten Matrix = " << i;
00221 #endif
00222         return(r=i);    // Rang=i : ist Anzahl Gl. fuer die SucheGl() erfolgreich
00223 }
00224 
00225 int LGSys::Untersuche(int rg)
00226 {       int     i;
00227         if(rg==0) return(R_IST_LOESUNG);
00228         if(st_fkt[rg-1] == n) return(KEINE_LOESUNG);
00229         aus = new int[n];
00230         for(i=0; i<=(n-rg); i++)
00231                 Loese(i);
00232         return(SPEZ_LOESUNG);
00233 }
00234 
00235 void LGSys::Ausgabe_Loesung(int ltyp)
00236 {
00237 #ifdef TALK
00238         int             i,j;
00239         double  d;
00240         std::cout << "\n";
00241         switch(ltyp)
00242         {
00243                 case KEINE_LOESUNG : std::cout << "\nGLSYS hat keine Lösung !\n"; break;
00244                 case R_IST_LOESUNG : std::cout << "\nGLSYS hat ganz R als Lösung !\n"; break;
00245                 case SPEZ_LOESUNG  :
00246                         if((n-r)>0)
00247                                 std::cout << "\nGLSYS hat " << n-r+1 << " linear unabhänige Lösungsungen:";
00248                         else
00249                                 std::cout << "\nGLSYS hat eine Lösung:";
00250                         for(i=0; i<=(n-r); i++)
00251                         {       std::cout << "\nP" << i << " = ( ";
00252                                 for(j=0; j<n; j++)
00253                                 {       std::cout << pn[i][j]; if(j<(n-1)) std::cout << " , "; }
00254                                 std::cout << " )";
00255                         }
00256                         for(i=0; i<=(n-r); i++)
00257                         {   if(i==0)    std::cout << "\n\nx = ( ";
00258                                 else    std::cout << " + " << i << " ( ";
00259                                 for(j=0; j<n; j++)
00260                                 {       d =  i==0 ? 0. : pn[0][j];
00261                                         std::cout << pn[i][j]-d; if(j<(n-1)) std::cout << " , ";
00262                                 }
00263                                 std::cout << " )";
00264                         }
00265                         break;
00266         }
00267 #endif
00268 }
00269 
00270 double LGSys::CalcPoly(double x, int k)
00271 {       int             j,i;
00272         double  y;
00273         if(n==r )
00274                 for(y=0., j=i=0; j < n; j++){
00275                         if(j == k) continue;
00276                         y += pn[i][j]*gpow(x,j);
00277                 }
00278         else
00279                 return 0.;
00280         return y;
00281 }
00282 
00283 double LGSys::GetPolyK(int k)
00284 {
00285         return pn[0][k];
00286 }
00287 
00288 void LGSys::Ausgabe_Glsys()
00289 {       int     i;
00290         for(i=0; i<m; i++)      // Gleichungen ausgeben
00291         {       gln[i]->P_Zeile(); std::cout << "     f(" << i+1 << ")=" << st_fkt[i]+1; }
00292         std::cout << "\n";
00293 }
00294 
00295 void LGSys::Loese(int k)
00296 {   int i,j,ki;
00297         pn[k] = new double[n];
00298         for(ki=j=i=0; i<n; i++) // Auswahl Liste aufstellen
00299                 if((j<=r)&&(i==st_fkt[j])) {    aus[i] = UNFREI; j++; }
00300                 else    if((++ki)==k)   { aus[i] = EINS; pn[k][i]=1.; }
00301                                 else    { aus[i] = FREI; pn[k][i]=0.; }
00302         Berechne(k);
00303 }
00304 
00305 void LGSys::Berechne(int k)
00306 {   int i,j;
00307         double  p;
00308         for(i=r-1; i>=0; i--)
00309         {       for(p=gln[i]->Wert(n), j=n-1; j>st_fkt[i]; j--)
00310                 {       if(aus[j]==EINS) p -= gln[i]->Wert(j);
00311                         else    if(aus[j]==UNFREI) p -= pn[k][j]*gln[i]->Wert(j);
00312                         // sonst FREI
00313                 }
00314                 pn[k][j] = p /= gln[i]->Wert(j);
00315         }
00316 }
00317 
00318 #ifdef STANDALONE
00319 main(char argc, char *argv[])
00320 {
00321         StatInp *s;
00322         std::cout.precision(20);
00323         std::cout << "REGRES Grad Datei [-yx]\n";
00324         if(argc == 2) Talk=1;
00325         if(argc >= 3)
00326                 s = new StatInp(argv[1], argv[2], argc==4 );
00327         else
00328                 s = new StatInp;
00329         exit(s->Result());
00330         delete s;
00331 }
00332 #endif

Generated on Sat Apr 1 09:04:03 2006 for GXSM by  doxygen 1.4.6