00001 #include "matrixutil.hpp"
00002 #include <cmath>
00003 #include <iostream>
00004 #include "vc6compat.h"
00005 using namespace std;
00006
00007 #define TRACE(a)
00008 #define TRACEX(a, b)
00009 #define SQR(X) ((X)*(X))
00010
00011
00012 bool QR (int zeilen, int spalten, double **A, double *d, double *b, const double epsilon)
00013 {
00014 if (zeilen<spalten) {
00015 throw("Matrix darf nicht weniger Zeilen als Spalten haben !");
00016 }
00017
00018 bool singular=false;
00019 double altenorm,hilfsnorm,beta, produkt;
00020 altenorm=0;
00021 for (int j=0; j<spalten; j++) {
00022
00023
00024
00025 hilfsnorm=0;
00026 for (int my=j+1; my<zeilen; my++) {
00027 hilfsnorm+=SQR(A[my][j]);
00028 }
00029
00030
00031
00032
00033 TRACEX("Vor der Transformation :",A);
00034 TRACE(hilfsnorm);
00035
00036 if (SQR(A[j][j])<SQR(epsilon)*hilfsnorm) {
00037 A[j][j]=sqrt(hilfsnorm);
00038 d[j]=-A[j][j];
00039 cerr<<"Diagonal-elem. "<<j<<" = 0"<<endl;
00040 } else {
00041 d[j]=-signum(A[j][j])*sqrt(hilfsnorm+SQR(A[j][j]));
00042
00043
00044 A[j][j]-=d[j];
00045 }
00046
00047
00048
00049
00050
00051
00052
00053 if (fabs(d[j])<epsilon*altenorm) {
00054 singular=true;
00055 break;
00056 }
00057
00058 altenorm=fabs(d[j]);
00059
00060
00061 beta=2.0/(hilfsnorm+SQR(A[j][j]));
00062
00063 TRACEX("nach der Transformation "<<j,A);
00064 TRACE(beta);
00065
00066
00067
00068 for (int k=j+1; k<spalten; k++) {
00069
00070
00071 produkt=0;
00072 for (int z=j; z<zeilen; z++) {
00073 produkt+=A[z][j]*A[z][k];
00074 }
00075 produkt*=beta;
00076 TRACE(produkt);
00077
00078 for (int z=j; z<zeilen; z++) {
00079 A[z][k]-=produkt*A[z][j];
00080 }
00081 }
00082
00083 produkt=0;
00084 for (int z=j; z<zeilen; z++) {
00085 produkt+=A[z][j]*b[z];
00086 }
00087 produkt*=beta;
00088 TRACE(produkt);
00089
00090 for (int z=j; z<zeilen; z++) {
00091 b[z]-=produkt*A[z][j];
00092 }
00093
00094 TRACE(A);
00095 }
00096 if (singular) return true;
00097 return false;
00098 }
00099
00106
00107 void rdsolve(int spalten, double **R, double *d, double *c, double *x)
00108 {
00109 double tempx;
00110 for (int j=spalten-1; j>=0; j--) {
00111 tempx=c[j];
00112
00113
00114 for (int k=j+1; k<spalten; k++)
00115 tempx-=R[j][k]*x[k];
00116
00117 x[j]=tempx/d[j];
00118 }
00119 }
00120
00121
00122
00123
00124
00125
00126 void Invert_RtR(double **R, double **I, int n)
00127 {
00128 int i, j, k;
00129
00130
00131
00132 for (i = 0; i < n; i++) {
00133 for (j = 0; j < i; j++)
00134 I[i][j] = 0;
00135 I[i][i] = 1;
00136 if (!R[i][i])
00137 throw("Singular matrix in Invert_RtR");
00138 }
00139
00140
00141
00142 for (k = 0; k < n; k++) {
00143 for (i = k; i < n; i++) {
00144 double s = I[i][k];
00145 for (j = k; j < i; j++)
00146 s -= R[j][i] * I[j][k];
00147 I[i][k] = s / R[i][i];
00148 }
00149 }
00150
00151
00152 for (k = 0; k < n; k++) {
00153 for (i = n - 1; i >= k; i--) {
00154 double s = I[i][k];
00155 for (j = i + 1; j < n; j++)
00156 s -= R[i][j] * I[j][k];
00157 I[i][k] = s / R[i][i];
00158 }
00159 }
00160 }
00161
00162 void compute_errors(int num_param, int num_data, double **R, double *d, double *b, double *errors)
00163 {
00164
00165
00166 double chisq=0;
00167 for (int i=num_param; i<num_data; i++) {
00168 chisq+=SQR(b[i]);
00169 }
00170
00171
00172 if (num_param>=num_data) throw("Error: Parameter errors only für num_data < num_data");
00173 chisq=sqrt(chisq/(num_data-num_param));
00174
00175
00176 for (int r=0; r<num_param; r++) {
00177 R[r][r]=d[r];
00178 }
00179
00180 double **C;
00181 reserve_2D(C, num_param, num_param);
00182 Invert_RtR(R, C, num_param);
00183
00184 for (int r=0; r<num_param; r++) {
00185 errors[r]=sqrt(C[r][r])*chisq;
00186 }
00187
00188 delete_2D(C);
00189
00190 }