Пример #1
0
int main( int args, char **argc )
{
	int i;
	double radii[4]    =  { 1, 4.657, 10, 42 };
	int moneyValues[4] =  { 20, 79, 10, 42 };
	int times[3][2]    = {{ 1045, 345 },
			      { 800, 435 },
			      { 2300, 300 }};

	for( i = 0; i < 11; i++ ) {
		if( i%4 == 0 ) printf( "\n" );

		// Execution of part 1
		if( i < 4 ) printf( "The volume for a sphere with radius %g is %3.7f\n", radii[i], volumeForRadius( radii[i] ));
		
		// Execution of part 2
		if( i > 3 && i < 8 ) getChange( moneyValues[i%4]);
		
		// Execution of part 3
		if( i > 7 ) printf( "Start time is %d. Duration is %d. End time is %d\n", times[i%4][START], times[i%4][DURATION], addTimes( times[i%4][START], times[i%4][DURATION] )); 
	}
}
void main()
{
	printSinus();
	printSinusWithError();
	getChange();


	FILE *point;
	double *x, *W, *f, *Zx, x_p, sum, *vs, *Bb, **Vsmtr, **VsmtrB, **Matr, *pr, sum_f, h_x, bet;//Bb - векторглобальныйправаячасть
	int i, j, l, *ll, **Nvtr, c, mu, v, flag,ff=1,oo=1;
	int kol, obl;//кол-во точек кинули
	point = fopen("point.txt", "r");
	fscanf(point, "%lf", &bet);
	fscanf(point, "%d", &kol);
	W = new double[kol + 1];// омега- вес каждой точки
	for (int i = 0;i <= kol;i++)W[i] = 1;
	
	x = new double[kol + 1];
	f = new double[kol + 1];
	x[0] = 0;
	f[0] = 0;
	//бросаем точки
	for (i = 1;i <= kol;i++)
		fscanf(point, "%lf", &x[i]);
	for (i = 1;i <= kol;i++)
		fscanf(point, "%lf", &f[i]);

	fscanf(point, "%d", &l);// l - кол-во областей
	//ll[i] - кол-во точек в i-ой области
	ll = new int[l + 1];
	ll[0] = 0;
	for (i = 1;i <= l;i++)
		fscanf(point, "%d", &ll[i]);

	Zx = new double[l + 2];// значения узлов по х

	Zx[0] = 0;
	for (i = 1;i < l + 2;i++)
		fscanf(point, "%lf", &Zx[i]);
	double h1;
	fscanf(point, "%lf", &h1);
	fclose(point);

	//вспомогательный для локального вектора
	vs = new double[5];
	vs[0] = 0;
	//вспомогательная матрица для локальной
	Vsmtr = new double*[5];
	for (i = 0; i < 5; i++)
		Vsmtr[i] = new double[5];

	///основная матрица
	Matr = new double*[2 * l + 3];
	for (i = 0; i < 2 * l + 3; i++)
		Matr[i] = new double[2 * l + 3];
	//ос ве
	Bb = new double[2 * l + 3];
	Nvtr = new int*[l + 1];
	for (i = 0; i <= l + 1; i++)
		Nvtr[i] = new int[5];
	for (i = 0;i < 5;i++)
		Nvtr[0][i] = 0;

	for (i = 0;i <= l;i++)
		Nvtr[i][0] = 0;

	for (i = 1;i <= l;i++)
	{
		for (j = 1;j < 5;j++)
		{
			Nvtr[i][j] = i * 2 - 1 + j - 1;
		}
	}
	double nev = 1;
	FILE *fid;
	fid = fopen("test1.csv", "w");
	if (!fid)
		printf("File is not opened");
	FILE *fid2;
	fid2 = fopen("test2.csv", "w");
	if (!fid2)
		printf("File is not opened");
	while (ff == 1 && nev>0.00001 && oo<100000) {

		for (i = 0;i < 2 * l + 3;i++)
			Bb[i] = 0;

		for (i = 0;i < 5;i++)
			Vsmtr[i][0] = 0;
		for (j = 0;j < 5;j++)
			Vsmtr[0][j] = 0;
		Bb[i] = 0;

		for (i = 0;i < 2 * l + 3;i++)
		{
			for (j = 0;j < 2 * l + 3;j++)
				Matr[i][j] = 0;
		}


		//для каждой области считаем матрицу локальную
		for (int k = 1; k <= l; k++)
		{//шаги по х

			h_x = Zx[k + 1] - Zx[k];

			for (int m1 = 1; m1 < 5; m1++)
			{
				for (int m2 = 1; m2 < 5; m2++)
				{
					sum = 0;
					for (int c = ll[k - 1] + 1; c <= ll[k] + ll[k - 1]; c++) //ll[i] - кол-во точек в i-ой области
					{
						x_p = x[c] - Zx[k];
						sum = sum + psi_matrix(m1, m2, x_p, h_x)*W[c];
					}
					Vsmtr[m1][m2] = sum;

				}
			}

			//матрица для регулязации
			//локальная
			VsmtrB = new double*[5];
			for (i = 0; i < 5; i++)
				VsmtrB[i] = new double[5];
			for (i = 0;i < 5;i++)
				VsmtrB[i][0] = 0;
			for (j = 0;j < 5;j++)
				VsmtrB[0][j] = 0;

			VsmtrB[1][1] = 60 * bet / pow(h_x, 3);
			VsmtrB[1][2] = 30 * bet / pow(h_x, 2);
			VsmtrB[1][3] = -60 * bet / pow(h_x, 3);
			VsmtrB[1][4] = 30 * bet / pow(h_x, 2);

			VsmtrB[2][1] = 30 * bet / pow(h_x, 2);
			VsmtrB[2][2] = 16 * bet / h_x;
			VsmtrB[2][3] = -30 * bet / pow(h_x, 2);
			VsmtrB[2][4] = 14 * bet / h_x;

			VsmtrB[3][1] = -60 * bet / pow(h_x, 3);
			VsmtrB[3][2] = -30 * bet / pow(h_x, 2);
			VsmtrB[3][3] = 60 * bet / pow(h_x, 3);
			VsmtrB[3][4] = -30 * bet / pow(h_x, 2);

			VsmtrB[4][1] = 30 * bet / pow(h_x, 2);
			VsmtrB[4][2] = 14 * bet / h_x;
			VsmtrB[4][3] = -30 * bet / pow(h_x, 2);
			VsmtrB[4][4] = 16 * bet / h_x;

			for (int m1 = 1; m1 < 5; m1++)
			{
				for (int m2 = 1; m2 < 5; m2++)
				{
					Vsmtr[m1][m2] = Vsmtr[m1][m2] + VsmtrB[m1][m2];
				}
			}


			for (int m1 = 1; m1 < 5; m1++)
			{
				for (int m2 = 1; m2 < 5; m2++)
				{
					mu = Nvtr[k][m1];
					v = Nvtr[k][m2];
					Matr[mu][v] = Matr[mu][v] + Vsmtr[m1][m2];
				}
			}

		}


		//для каждой области считаем вектор F
		for (int k = 1; k <= l; k++)
		{//шаги по х
			double h_x = Zx[k + 1] - Zx[k];

			for (int m1 = 1; m1 < 5; m1++)
			{
				sum = 0;

				for (int c = ll[k - 1] + 1; c <= ll[k] + ll[k - 1]; c++) //ll[i] - кол-воточеквi-ойобласти
				{
					x_p = x[c] - Zx[k];
					sum = sum + psi_vector(m1, x_p, h_x)*f[c]*W[c];
				}
				vs[m1] = sum;
			}

			//в массиве nvtr  хранится номера глобальных бф 
			//заполняем глобальный вектор B
			for (i = 1;i < 5;i++)
			{
				c = Nvtr[k][i];
				Bb[c] = Bb[c] + vs[i];
			}

		}
		FILE *fp;
		fp = fopen("matric.txt", "w");
		fprintf(fp, "%d\n", 2 * l + 2);
		for (i = 1;i < 2 * l + 3;i++)
		{
			for (j = 1;j < 2 * l + 3;j++)
			{
				fprintf(fp, "%lf ", Matr[i][j]);
			}
			fprintf(fp, "\n");
		}
		fprintf(fp, "\n");
		for (j = 1;j < 2 * l + 3;j++)
			fprintf(fp, "%lf ", Bb[j]);

		//решение слау

		double **t, s, *q;
		int m = 2 * l + 2;
		q = new double[m + 1];

		t = new double*[m + 1];
		for (int i = 0;i <= m;i++)
			t[i] = new double[m + 1];

		for (int k = 1;k <= m - 1;k++)
		{
			maxzam(Matr, Bb, k, m);
			for (int i = k + 1;i <= m;i++)
			{
				t[i][k] = Matr[i][k] / Matr[k][k];
				Bb[i] = Bb[i] - t[i][k] * Bb[k];
				for (int j = k + 1;j <= m;j++)
					Matr[i][j] = Matr[i][j] - t[i][k] * Matr[k][j];
			}
		}

		q[m] = Bb[m] / Matr[m][m];


		for (int k = m - 1; k >= 1; k--)
		{
			s = 0;
			for (int j = k + 1;j <= m;j++)
			{
				s = s + Matr[k][j] * q[j];
			}

			q[k] = (Bb[k] - s) / Matr[k][k];
		}

		fprintf(fp, "\n");
		fprintf(fp, "\n");

		for (int i = 1;i <= 2 * l + 2;i++)
			fprintf(fp, "%lf ", q[i]);
		fclose(fp);

		// строим сплайн 
		double *xxx, *sp;
		int ktx = int((Zx[l + 1] - Zx[1]) / h1) + 1;
		xxx = new double[ktx + 1];
		pr = new double[ktx + 1];
		sp = new double[kol + 1];

		for (int i = 1;i <= ktx;i++)
		{
			xxx[i] = h1*(i - 1);
			
		}
		double ns1 = 0,ns2=0;
		//строим сплайн по шагам
		for (int j = 1;j <= ktx;j++)
		{
			flag = 0;
			for (int k = 1;(k <= l && flag == 0);k++)
			{
				if (xxx[j] <= Zx[k + 1] && xxx[j] >= Zx[k])
				{
					obl = k;
					flag = 1;
				}
			}
			x_p = xxx[j] - Zx[obl];
			h_x = Zx[obl + 1] - Zx[obl];
			sum_f = 0;
			for (int g = 1;g <= 4;g++)
			{
				int nn = Nvtr[obl][g];
				sum_f = sum_f + psi_vector(g, x_p, h_x)*q[nn];
			}
			pr[j] = sum_f;
			if (oo == 1)fprintf(fid, " %.2f; %.5f\n", xxx[j], pr[j]);
			else
			{
				fprintf(fid2, " %.2f; %.5f\n", xxx[j], pr[j]);
			}

			ns1 = ns1 + pr[j] * pr[j];
			ns2 = ns2 + (xxx[j] * xxx[j] / 2 - pr[j])*(xxx[j] * xxx[j] / 2 - pr[j]);
		}
		ns1 = sqrt(ns1);
		ns2 = sqrt(ns2);
	
		nev = ns2 / ns1;
		printf("%lf ", nev);
		//считаем сплайн в точках,которые кинули 
		for (int j = 1;j <= kol;j++)
		{
			flag = 0;
			for (int k = 1;(k <= l && flag == 0);k++)
			{
				if (x[j] <= Zx[k + 1] && x[j] >= Zx[k])
				{
					obl = k;
					flag = 1;
				}
			}
			x_p = x[j] - Zx[obl];
			h_x = Zx[obl + 1] - Zx[obl];
			sum_f = 0;
			for (int g = 1;g <= 4;g++)
			{
				int nn = Nvtr[obl][g];
				sum_f = sum_f + psi_vector(g, x_p, h_x)*q[nn];
			}
			sp[j] = sum_f;

		}
		//считаем среднее отклонение
		double sss = 0;

		for (int j = 1;j <= kol;j++)
			sss = sss + fabs(f[j] - sp[j]);
		sss = sss / kol; //sss - среднее отклонение
		i = 0;
		for (int j = 1;j <= kol;j++)
		{
			if (fabs(f[j] - sp[j]) > 2*sss) {
				i++;
				printf("oo = %d j = %d sss = %lf f= %lf  sp=%lf \n",oo, j, sss, f[j], sp[j]);
				W[j] = W[j] * 0.9;
			}
		}
		if (i > 0) 
		{ ff = 1;
		oo = oo + 1; }
	else ff = 0;
	}
		
			
	_getch();
}