00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
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
00051
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++)
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++)
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++)
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
00208 std::cout << "\nSchritt " << i+1 << " : ";
00209 #endif
00210 if(SucheGl(i)==NEG) break;
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);
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++)
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++)
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
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