Хочу получить удостоверение. Сколько стоит оплата? |
Конструкторы и деструкторы
Конструктор (constructor) — это функция-член (метод) класса. Конструкторы используются для инициализации переменных класса или для выделения памяти. Они всегда имеют такое же имя, как и класс, в котором они определены. Конструкторы располагают дополнительными возможностями: они могут иметь аргументы и их можно перегружать.
Деструктор (destructor) — это метод класса, использующийся обычно для освобождения памяти, выделенной из свободной памяти. Деструктор, так же как и конструктор, имеет такое же имя, как и класс, в котором он описан, перед которым находится символ "тильда" (~). Деструкторы являются дополнениями конструкторов. Деструктор вызывается автоматически при использовании операции delete по отношению к указателю класса или в случае, когда программа выходит из области действия объекта класса. Деструкторы, в отличие от конструкторов, не могут иметь параметров, и их нельзя перегружать.
В приводимой ниже программе конструктор nonlinear_regression() используется для инициализации локальных переменных класса nonlinear_regression. Программа рассчитывает нелинейную регрессию. Алгоритм расчета нелинейной регрессии хорошо описан в книге К. Эберт, Х. Эдерер /Компьютеры. Применение в химии. М.: Мир., 1988. С.284.
//========================================================== // Name : constructor.cpp // Author : Marat // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //========================================================== #include <iostream> using namespace std; #include<stdlib.h> #include<math.h> #define ARRAY_SIZE 100 //Размер матрицы #define np 64 //Число пар данных //Экспериментальные значения X(i) double xx[np+1]={0.000, 0.000, 0.005, 0.010, 0.015, 0.020, 0.025, 0.030, 0.035, 0.040, 0.045, 0.050, 0.055, 0.060, 0.065, 0.070, 0.075, 0.080, 0.085, 0.090, 0.095, 0.100, 0.105, 0.110, 0.115, 0.120, 0.125, 0.130, 0.135, 0.140, 0.145, 0.150, 0.155, 0.160, 0.165, 0.170, 0.175, 0.180, 0.185, 0.190, 0.195, 0.200, 0.205, 0.210, 0.215, 0.220, 0.225, 0.230, 0.235, 0.240, 0.245, 0.250, 0.255, 0.260, 0.265, 0.270, 0.275, 0.600, 0.605, 0.610, 0.615, 0.620, 0.625, 0.630, 0.635 }; //Экспериментальные значения Y(i) double yy[np+1]={0.000000, 1.000000, 0.854415, 0.734266, 0.627988, 0.535742, 0.459174, 0.395416, 0.337545, 0.288678, 0.249475, 0.213886, 0.185657, 0.157447, 0.135157, 0.118451, 0.099275, 0.085432, 0.074251, 0.063035, 0.054768, 0.047787, 0.039426, 0.034518, 0.030223, 0.026509, 0.023732, 0.019806, 0.014693, 0.011894, 0.009542, 0.006593, 0.005535, 0.005540, 0.007713, 0.003393, 0.004965, 0.001981, 0.003614, 0.000934, 0.0000215, 0.0002637, 0.0013670, 0.0011571, -.0006458, 0.00199994, -.0035763, -.0026426, -.0023520, -.0026480, -.0054493, -.0026830, -.0028068, -.0018326, -.0008719, -.0006889, -.0008531, -.0052879, -.0058611, -.0047900, -.0052341, -.0022847, -.0024500, -.0030974, -.0}; class nonlinear_regression { long double a[ARRAY_SIZE][ARRAY_SIZE], b[ARRAY_SIZE][ARRAY_SIZE], u[ARRAY_SIZE][ARRAY_SIZE]; long double v[ARRAY_SIZE][ARRAY_SIZE], w[ARRAY_SIZE][ARRAY_SIZE], f2[ARRAY_SIZE][ARRAY_SIZE]; long double x[ARRAY_SIZE], x9[ARRAY_SIZE], f[ARRAY_SIZE], f9[ARRAY_SIZE]; long double f0[ARRAY_SIZE], f1[ARRAY_SIZE], h[ARRAY_SIZE], k[ARRAY_SIZE]; int i,j; int n; long double ss; //Сумма квадратов отклонений long double X,Y; long double ff; //Коэффициент оптимизации long double sm; public: //Конструктор nonlinear_regression() {n=3; ff=1; sm=1E100;} //Деструктор ~nonlinear_regression() {cout<<"\nThats all right!"<<endl;} void compute(); void input(); void inversion_matrix(); void partial_derivative(); void print(); void optimization_factor(); void sum_of_square_deviations(); void calculation(); void regression(); void function(); }; void nonlinear_regression::compute() { input(); for(int l=0;l<1000;l++) { l++; //Вычисление частных производных partial_derivative(); //Обращение матрицы inversion_matrix(); for(i=1;i<=n;i++) { h[i]=0; for(j=1;j<=n;j++) { h[i]+=w[i][j]*f9[j]; } } //Вывод данных if(l>998) print(); //Вычисление коэффициента оптимизации optimization_factor(); for(i=1;i<=n;i++) { x9[i]-=ff*h[i]; } } } void nonlinear_regression::input() { cout<<"\nInitial approximation input "; for(i=1;i<=n;i++) { cout<<"\nk["<<i<<"] = "; cin>>x[i]; x9[i]=x[i]; } } //Обращение матрицы. //Исходная матрица A, //Обращенная матрица W void nonlinear_regression::inversion_matrix() { int z,t,k; double s; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { b[i][j]=0; v[i][j]=0; if(i!=j) goto alpha; b[i][j]=1; v[i][j]=1; alpha: ; } } for(z=1;z<n;z++) { s=0; //Поиск ведущего элемента for(i=z;i<=n;i++) { if(s>fabs(a[i][z])) goto beta; s=fabs(a[i][z]); t=i; beta: ; } //Обмен z-й строки с t-й for(i=1;i<=n;i++) { s=a[z][i]; a[z][i]=a[t][i]; a[t][i]=s; } if(fabs(a[z][z])>1E-30) goto gamma; cout<<"\nThe matrix cannot be inversed!"; exit(1); gamma: v[z][z]=0; v[t][t]=0; v[z][t]=1; v[t][z]=1; //Исключение недиагональных элементов методом Жордана-Гаусса for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(i==z) goto teta; if(j==z) goto epsilon; u[i][j]=a[i][j]-a[z][j]*a[i][z]/a[z][z]; goto psi; teta: if(i==j) goto omega; u[i][j]=-a[i][j]/a[z][z]; goto psi; omega: u[z][z]=1/a[z][z]; goto psi; epsilon: u[i][z]=a[i][z]/a[z][z]; psi: ; } } //Умножение матриц //B = V * B for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { w[i][j]=0; for(k=1;k<=n;k++) { w[i][j]+=v[i][k]*b[k][j]; } } } for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { b[i][j]=w[i][j]; } } for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { a[i][j]=u[i][j]; v[i][j]=0; if(i==j) v[i][j]=1; } } } //Результат умножения матрицы A на матрицу B for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { w[i][j]=0; for(k=1;k<=n;k++) { w[i][j]+=a[i][k]*b[k][j]; } } } } //Вычисление частных производных //(элементы массива a[]) в точках x9 void nonlinear_regression::partial_derivative() { int i3,j3; double di; int ip; ss=0; for(int i=1;i<=n;i++) { f9[i]=0; k[i]=x9[i]; for(j=1;j<=n;j++) { a[i][j]=0; } } for(int ip=1;ip<=np;ip++) { X=xx[ip]; function(); di=yy[ip]-Y; ss+=pow(di,2); for(int i3=1;i3<=n;i3++) { f9[i3]-=di*f1[i3]; for(j3=i3;j3<n;j3++) { a[i3][j3]-=di*f2[i3][j3]+f1[i3]*f1[j3]; } } } for(int i3=1;i3<=n;i3++) { for(j3=i3;j3<=n;j3++) { a[j3][i3]=a[i3][j3]; } } } //Y - функция, входящая в уравнение регрессии, //F1() и F2() - ее первые и вторые производные //по параметрам k // Y=k(1) + k(2)*exp(-k(3)*X) void nonlinear_regression::function() { f1[1]=1; f2[1][1]=0; f2[1][2]=0; f2[1][3]=0; f1[2]=exp(-k[3]*X); f2[2][2]=0; f2[2][3]=-X*f1[2]; f1[3]=k[2]*f2[2][3]; f2[3][3]=-X*f1[3]; Y=k[1]+k[2]*f1[2]; } //Вычисление суммы квадратов отклонений void nonlinear_regression::sum_of_square_deviations() { ss=0; for(int i=1;i<=np;i++) { X=xx[i]; regression(); Y-=yy[i]; ss+=pow(Y,2); } } //Уравнение регрессии void nonlinear_regression::regression() { Y=k[1]+k[2]*exp(-k[3]*X); } //Вычисление коэффициента оптимизации ff void nonlinear_regression::optimization_factor() { double fm,df; ff=0.6; fm=0; df=0.5; dzeta: calculation(); if(ss<sm) {sm=ss; fm=ff; ff+=df; goto dzeta;} else {ff=fm-df;} omega: calculation(); if(ss<sm) {sm=ss; fm=ff; ff-=df; goto omega;} for(j=0;j<=7;j++) { df/=2; ff=fm+df; calculation(); if(ss<sm) {sm=ss;fm=ff; goto csi;} else {ff=fm-df; calculation();} if(ss<sm) {sm=ss; fm=ff;} csi:; } ff=fm; } //Вспомогательная функция void nonlinear_regression::calculation() { for(int i=1;i<=n;i++) { k[i]=x9[i]-ff*h[i]; } sum_of_square_deviations(); } //Вывод данных на экран void nonlinear_regression::print() { for(int i=1;i<=n;i++) { cout<<"\nk["<<i<<"] = "<<x9[i]<<"+/-"<<pow(fabs(w[i][i]*ss/(np-n)),2); } cout<<"\nThe sum of square deviations is "<<ss<<endl; } int main() { nonlinear_regression data; data.compute(); return 0; }
Результат:
Initional approximation input k[1]=1 k[2]=1 k[3]=10 k[1]=-0.106121+/-1.37518e-007 k[2]=0.711263 +/-5.13888e-006 k[3]=10+/-0 The sum of square deviations is 0.645081