Задание №1
«Решение систем линейных алгебраических уравнений»
Составить программу решения СЛАУ порядка n и решить систему линейных уравнений пятого порядка с трехдиагональной симметричной матрицей вида
Метод |
d |
q |
MQ |
-2 |
-3.23 |
Построить график зависимости невязки Ø от порядка матрицы n, для чего провести расчеты для матриц размерностью 25, 50 и 75.
Листинг программы:
#include <iostream.h>
#include <math.h>
#include <iomanip.h>
int sign(double a)
{
if(a>0) return 1;
else if(a<0) return -1;
}
void main(void)
{
int i, j, n, k;
double A[75][75],S[75][75], q, d, o;
cout << " Vvedite q: ";
cin >> q;
cout << " Vvedite d: ";
cin >> d;
cout << " Vvedite n - razmernost' matrici A: ";
cin >> n;
//Zadaem matricy A
for (i=0;i<n;i++)
for (j=0;j<n;j++) {
A[i][j]=S[i][j]=0;
A[0][0]=A[n-1][n-1]=q;
for(k=1;k<n-1;k++) A[k][k]=-2;
}
for(i=0;i<n-1;i++) A[i][i+1]=A[i+1][i]=1;
// pryamoi hod vipolneniya
double B[75],X[75],D[75],Y[75],O[75];
double delta;
for(k=0;k<n;k++)
{
delta=A[k][k];
if(k!=0) for(i=0;i<=k-1;i++) delta=delta-D[i]*S[i][k]*S[i][k];
D[k]=sign(delta);
S[k][k]=sqrt(fabs(delta));
for(j=k+1;j<n;j++) {
delta=A[k][j];
if(k!=0) for(i=0;i<=k-1;i++) delta=delta-D[i]*S[i][k]*S[i][j];
S[k][j]=delta/(S[k][k]*D[k]);
}
}
//Vipolnenie algoritma - obratni hod
B[0]=B[n-1]=0;
for (i=1;i<n-1;i++) B[i]=d;
Y[0]=B[0]/(S[0][0]*D[0]);
for(i=1;i<n;i++)
{
delta=B[i];
for(k=0;k<=i-1;k++) delta=delta-D[k]*Y[k]*S[k][i];
Y[i]=delta/(S[i][i]*D[i]);
}
X[n-1]=Y[n-1]/S[n-1][n-1];
for(i=n-2;i>=0;i--)
{
delta=Y[i];
for(k=i+1;k<=n-1;k++) delta=delta-X[k]*S[i][k];
X[i]=delta/S[i][i];
}
//Vichislenie nevuazki o
for (i=0;i<n;i++) {
O[i]=B[i];
for (j=0;j<n;j++) O[i]=O[i]-X[j]*A[i][j];
}
//Poisk max O[i]
for (i=0;i<n-1;i++) {
o=fabs(O[i]);
if(fabs(O[i+1])>o) o=fabs(O[i+1]);
}
cout<<" Nevyazka ravna - "<<o<<endl;
//---------------------------------------------------------------25
cout << " Vvedite n - razmernost' matrici A: ";
cin >> n;
//Zadaem matricy A
for (i=0;i<n;i++)
for (j=0;j<n;j++) {
A[i][j]=S[i][j]=0;
A[0][0]=A[n-1][n-1]=q;
for(k=1;k<n-1;k++) A[k][k]=-2;
}
for(i=0;i<n-1;i++) A[i][i+1]=A[i+1][i]=1;
//Vipolnenie algoritma - pryamoi hod
for(k=0;k<n;k++)
{
delta=A[k][k];
if(k!=0) for(i=0;i<=k-1;i++) delta=delta-D[i]*S[i][k]*S[i][k];
D[k]=sign(delta);
S[k][k]=sqrt(fabs(delta));
for(j=k+1;j<n;j++) {
delta=A[k][j];
if(k!=0) for(i=0;i<=k-1;i++) delta=delta-D[i]*S[i][k]*S[i][j];
S[k][j]=delta/(S[k][k]*D[k]);
}
}
//Vipolnenie algoritma - obratni hod
B[0]=B[n-1]=0;
for (i=1;i<n-1;i++) B[i]=d;
Y[0]=B[0]/(S[0][0]*D[0]);
for(i=1;i<n;i++)
{
delta=B[i];
for(k=0;k<=i-1;k++) delta=delta-D[k]*Y[k]*S[k][i];
Y[i]=delta/(S[i][i]*D[i]);
}
X[n-1]=Y[n-1]/S[n-1][n-1];
for(i=n-2;i>=0;i--)
{
delta=Y[i];
for(k=i+1;k<=n-1;k++) delta=delta-X[k]*S[i][k];
X[i]=delta/S[i][i];
}
//Vichislenie nevuazki o
for (i=0;i<n;i++) {
O[i]=B[i];
for (j=0;j<n;j++) O[i]=O[i]-X[j]*A[i][j];
}
for (i=0;i<n-1;i++) {
o=fabs(O[i]);
if(fabs(O[i+1])>o) o=fabs(O[i+1]);
}
cout<<" Nevyazka ravna - "<<o<<endl;
//------------------------------------------------------------------50
cout << " Vvedite n - razmernost' matrici A: ";
cin >> n;
//Zadaem matricy A
for (i=0;i<n;i++)
for (j=0;j<n;j++) {
A[i][j]=S[i][j]=0;
A[0][0]=A[n-1][n-1]=q;
for(k=1;k<n-1;k++) A[k][k]=-2;
}
for(i=0;i<n-1;i++) A[i][i+1]=A[i+1][i]=1;
//Vipolnenie algoritma - pryamoi hod
for(k=0;k<n;k++)
{
delta=A[k][k];
if(k!=0) for(i=0;i<=k-1;i++) delta=delta-D[i]*S[i][k]*S[i][k];
D[k]=sign(delta);
S[k][k]=sqrt(fabs(delta));
for(j=k+1;j<n;j++) {
delta=A[k][j];
if(k!=0) for(i=0;i<=k-1;i++) delta=delta-D[i]*S[i][k]*S[i][j];
S[k][j]=delta/(S[k][k]*D[k]);
}
}
//Vipolnenie algoritma - obratni hod
B[0]=B[n-1]=0;
for (i=1;i<n-1;i++) B[i]=d;
Y[0]=B[0]/(S[0][0]*D[0]);
for(i=1;i<n;i++)
{
delta=B[i];
for(k=0;k<=i-1;k++) delta=delta-D[k]*Y[k]*S[k][i];
Y[i]=delta/(S[i][i]*D[i]);
}
X[n-1]=Y[n-1]/S[n-1][n-1];
for(i=n-2;i>=0;i--)
{
delta=Y[i];
for(k=i+1;k<=n-1;k++) delta=delta-X[k]*S[i][k];
X[i]=delta/S[i][i];
}
//Vichislenie nevuazki o
for (i=0;i<n;i++) {
O[i]=B[i];
for (j=0;j<n;j++) O[i]=O[i]-X[j]*A[i][j];
}
for (i=0;i<n-1;i++) {
o=fabs(O[i]);
if(fabs(O[i+1])>o) o=fabs(O[i+1]);
}
cout<<" Nevyazka = "<<o<<endl;
//---------------------------------------------------------------------------75
cout << " Vvedite n - razmernost' matrici A: ";
cin >> n;
//Zadaem matricy A
for (i=0;i<n;i++)
for (j=0;j<n;j++) {
A[i][j]=S[i][j]=0;
A[0][0]=A[n-1][n-1]=q;
for(k=1;k<n-1;k++) A[k][k]=-2;
}
for(i=0;i<n-1;i++) A[i][i+1]=A[i+1][i]=1;
for(k=0;k<n;k++)
{
delta=A[k][k];
if(k!=0) for(i=0;i<=k-1;i++) delta=delta-D[i]*S[i][k]*S[i][k];
D[k]=sign(delta);
S[k][k]=sqrt(fabs(delta));
for(j=k+1;j<n;j++) {
delta=A[k][j];
if(k!=0) for(i=0;i<=k-1;i++) delta=delta-D[i]*S[i][k]*S[i][j];
S[k][j]=delta/(S[k][k]*D[k]);
}
}
// obratni hod vipolneniya
B[0]=B[n-1]=0;
for (i=1;i<n-1;i++) B[i]=d;
Y[0]=B[0]/(S[0][0]*D[0]);
for(i=1;i<n;i++)
{
delta=B[i];
for(k=0;k<=i-1;k++) delta=delta-D[k]*Y[k]*S[k][i];
Y[i]=delta/(S[i][i]*D[i]);
}
X[n-1]=Y[n-1]/S[n-1][n-1];
for(i=n-2;i>=0;i--)
{
delta=Y[i];
for(k=i+1;k<=n-1;k++) delta=delta-X[k]*S[i][k];
X[i]=delta/S[i][i];
}
//Vichislenie nevuazki o
for (i=0;i<n;i++) {
O[i]=B[i];
for (j=0;j<n;j++) O[i]=O[i]-X[j]*A[i][j];
}
for (i=0;i<n-1;i++) {
o=fabs(O[i]);
if(fabs(O[i+1])>o) o=fabs(O[i+1]);
}
cout<<" Nevyazka ravna - "<<o<<endl;
}
Рисунок 1 - Результат:
Задание №3
«Аппроксимация функций»
Во всех вариантах требуется аппроксимировать заданную исходную функцию f(x) многочленом на интервале [a, b]. Дано количество неизвестных параметров n, вид аппроксимации и m - количество точек, в которых задана функция. Таблица исходной функции yi=f(xi) вычисляется в точках xi=a+(i-1)(b-a)/(m-1), i=1..m. Используя полученную таблицу (xi, yi), требуется вычислить значения функций f(xj), φ(xj,) и погрешность d(xj)= f(xj)- φ(xj,) в точках xj=a+(j-1)(b-a)/20; j=1..21, построить графики и проанализировать качество полученной аппроксимации.
Функция f(x) |
a |
b |
m |
n |
Вид аппроксимации |
1 |
8 |
4 |
4 |
Лагранжа PL |
Листинг программы:
#include <iostream.h>
#include <math.h>
#include <stdio.h>
double y_x(double);
double Mn_L(double*,double,int);
//-------Ish. funkciya---------
double y_x(double x) {
return log(x)-5.*cos(x);
}
//-------Polinom Lagrandga------
double Mn_L(double *x,double xt,int n) {
int i,k;
double e,p=0;
for(k=0;k<n;k++)
{
e=1.;
for (i=0;i<n;i++)
if (i!=k) e *= ((xt-x[i])/(x[k]-x[i]));
p += e*y_x(x[k]);
}
return p;
}
Void main(void)
{
//--------Nachal. znacheniya-----
double x,a,b,h,h1,*mas_x;
int i,n,m;
cout << " Vvedite a: ";
cin >> a;
cout << " Vvedite b: ";
cin >> b;
cout << " Vvedite n: ";
cin >> n;
cout << " Vvedite m: ";
cin >> m;
h=(b-a)/(m-1);
h1=(b-a)/20;
mas_x=new double[m];
for(x=a,i=0;i<m;i++){
mas_x[i]=x;
x+=h;
}
//----------Vivod rezultata--------
printf(" x f(x) ~f(x) df(x)\n");
printf("------------------------------------\n");
for(x=a,i=1;i<=21;i++,x+=h1)
printf("%3.2f %7.3f %7.3f %7.3f\n",x,y_x(x),Mn_L(mas_x,x,n),y_x(x)-Mn_L(mas_x,x,n));
cout<<endl;
delete []mas_x;
}
Рисунок 2 – Результат
Задание №4
«Вычисление производных и интегралов»
Задан интервал , функция и указан метод вычисления интеграла. Вначале вычислить точные выражения для первой, второй производных , и для интеграла. Затем необходимо составить подпрограмму для вычисления первой и второй производных, и подпрограмму вычисления интеграла указанным методом. Составить основную программу, которая вычисляет таблицу значений функции, ее точных и приближенных производных в точках , а также точное и приближенное значения интеграла. Вторую производную вычислять только во внутренних точках.
Расчеты производной произвести для . Расчеты интеграла произвести для и с точностью .
Проанализировать погрешность вычислений, для чего построить графики и вычислить погрешности производных и интеграла.
Функция |
a |
b |
Метод интегрирования |
Значение |
1 |
8 |
Симпсона |
8.896 |
Листинг программы:
#include <math.h>
#include <stdio.h>
#include <iostream.h>
double func(double); //vichislenie znacheniy funkcii
double toch_dif_1(double);//vichislenie znacheniy proizvodnoi funkcii
double toch_dif_2(double);//vichislenie znacheniy vtoroi proizvodnoi funkcii
double pribl_integr(double (*f)(double), double, double, double);//vichislenie znacheniy integrala met. Simpsona
double pribl_dif_1(double (*f)(double), double, double, double, double);//vichislenie znacheniy pribligennoi proizvodnoi funkcii
double pribl_dif_2(double (*f)(double), double, double, double, double);//vichislenie znacheniy pribligennoi vtoroi proizvodnoi funkcii
double func(double x)
{ return (log(x)-5.*cos(x));} //f(x)=ln(x)-5cos(x)
double toch_dif_1(double x)
{ return (1/x+5*sin(x));}//f'(x)=1/x+5sin(x)
double toch_dif_2(double x)
{ return (-1./(x*x)+5.*cos(x));}//f''(x)=-1/x^2+5cos(x)
double pribl_dif_1(double (*f)(double), double x, double a, double b, double h) {
if (x==a) return -(3*f(x)-4*f(x+h)+f(x+2*h))/(2*h);
else
if (x==b) return ((*f)(x-2*h)-4*(*f)(x-h)+3*(*f)(x))/(2*h);
else
return ((*f)(x+h)-(*f)(x-h))/(2*h);
}
double pribl_dif_2(double (*f)(double), double x, double a, double b, double h) {
return ((*f)(x-h)-2*(*f)(x)+(*f)(x+h))/(h*h);
}
double pribl_integr(double (*f)(double), double a, double b, double m)//metod Simpsona
{ double s=0,h,x;
h=(b-a)/m;
x=a;
for(int i=1;i<=m;i++) {
s+=f(x)+4*f(x+h/2)+f(x+h);
x+=h;
}
return (s*h/6);
}