1-курс / Kursak 33+ / Курсовая
.docМіністерство освіти та науки України
Дніпропетровський національний університет
Факультет фізики, електроніки та
комп’ютерних систем
Кафедра прикладної та
комп’ютерної радіофізики
Курсова робота
з дисципліни
“Обчислювальна техніка та программування”
Виконав: студент гр. КП-10-1
Х. Ф. Сапаев
Дніпропетровськ 2011
Задание к курсовой работе
Составить программу для вычисления заданной специальной функции, используя известное интегральное представление и разложение в ряд. Рассчитать значения функции в некотором интервале значений аргумента (в зависимости от области определения) и построить графики функции для интегрального представления и разложения в ряд. Для вычисления функции по ее интегральному представлению использовать численное интегрирование по методу Симпсона:
,
где h – шаг разбиения интервала (a,b).
Создать диалоговое Windows приложение на языке программирования ФОРТРАН или С++. Ввод данных – в поля ввода диалогового окна. Вывод результатов – в виде графика функции в окно приложения. На графике должны быть отображены две кривые: для интегрального представления и для разложения в ряд.
Гиперболический арккосинус
// KursakDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Kursak.h"
#include "KursakDlg.h"
#include <math.h>
#include <stdio.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CKursakDlg dialog
CEdit* pEdit_min_x; // массив указателей на Edit Control для минимального значения X
CEdit* pEdit_min_y; // массив указателей на Edit Control для минимального значения X
CEdit* pEdit_max_x; // массив указателей на Edit Control для максимального значения X
CEdit* pEdit_max_y; // массив указателей на Edit Control для максимального значения Y
CEdit* pEdit_grid; // массив указателей на Edit Control для значения сетки
CEdit* pEdit_num; // массив указателей на Edit Control для значения числа дискретных значений графика
CEdit* pEdit_ei;
CEdit* pEdit_n;
double* x; // массив со значениями x
double* y_integral; // массив со значениями функции посчитаными по интегральному представлению
double* y_ryad; // массив со значениями функции посчитаными по разложению в ряд
float xMin=1, xMax=10, yMin=0, yMax=3; // значения, ограничивающие область
int Num = 100; // число дискретных значений графика
char strBuffer[20]; // вспомагательный текстовый буфер
float ei = 0.001; // точность вичислений для интегрального представления
int N = 0;
#define X_EXT 1000 // Протяженность отображения по X
#define Y_EXT 1000 // Протяженность отображения по Y
int GRIDNUM=10; // Размер сетки
#define PI 3.14159265358979323846
double X;
long double pows(long double, long double);
long double r(long double); // Функция разложения в ряд
long double fact(int); // Функция факториала
// Функция интегрального представления
long double f(long double); // Функция функции в интеграле
/* Прототип фун – ции, вычисляющей интеграл */
float integral(float a, float b, float e);
CKursakDlg::CKursakDlg(CWnd* pParent /*=NULL*/)
: CDialog(CKursakDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CKursakDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CKursakDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON1, &CKursakDlg::OnBnClickedButton1)
// ON_WM_SHOWWINDOW()
//ON_WM_UPDATEUISTATE()
END_MESSAGE_MAP()
// CKursakDlg message handlers
BOOL CKursakDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// выделения памяти под указатели
x = new double[Num];
y_integral = new double[Num];
y_ryad = new double[Num];
pEdit_min_x = new CEdit[2];
pEdit_max_x = new CEdit[2];
pEdit_min_y = new CEdit[2];
pEdit_max_y = new CEdit[2];
// Инициализирование массивов указателей на соответствующие элементы управления
pEdit_min_x = (CEdit*)GetDlgItem(IDC_MINX);
pEdit_max_x = (CEdit*)GetDlgItem(IDC_MAXX);
pEdit_min_y = (CEdit*)GetDlgItem(IDC_MINY);
pEdit_max_y = (CEdit*)GetDlgItem(IDC_MAXY);
pEdit_grid = (CEdit*)GetDlgItem(IDC_GRID);
pEdit_num = (CEdit*)GetDlgItem(IDC_NUM);
pEdit_ei = (CEdit*)GetDlgItem(IDC_EI);
// Заполнение элементов управления Edit Control значениями по умолчанию
sprintf( strBuffer,"%g", xMin );
pEdit_min_x->SetWindowText((CString) strBuffer);
sprintf( strBuffer,"%g", xMax );
pEdit_max_x->SetWindowText((CString) strBuffer);
sprintf( strBuffer,"%g", yMin );
pEdit_min_y->SetWindowText((CString) strBuffer);
sprintf( strBuffer,"%g", yMax );
pEdit_max_y->SetWindowText((CString) strBuffer);
sprintf( strBuffer,"%i", GRIDNUM );
pEdit_grid->SetWindowText((CString) strBuffer);
sprintf( strBuffer,"%i", Num );
pEdit_num->SetWindowText((CString) strBuffer);
sprintf( strBuffer,"%f", ei );
pEdit_ei->SetWindowText((CString) strBuffer);
return TRUE;
}
void CKursakDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CKursakDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CKursakDlg::OnBnClickedButton1()
{
// Считывание значений параметров программы, заданных в элементах управления
pEdit_min_x->GetWindowText((LPTSTR) strBuffer,20);
sscanf(strBuffer, "%f", &xMin );
pEdit_max_x->GetWindowText((LPTSTR) strBuffer,20);
sscanf( strBuffer, "%f", &xMax );
pEdit_min_y->GetWindowText((LPTSTR) strBuffer,20);
sscanf( strBuffer, "%f", &yMin );
pEdit_max_y->GetWindowText((LPTSTR) strBuffer,20);
sscanf( strBuffer, "%f", &yMax );
pEdit_grid->GetWindowText((LPTSTR) strBuffer,20);
sscanf( strBuffer, "%i", &GRIDNUM );
pEdit_num->GetWindowText((LPTSTR) strBuffer,20);
sscanf( strBuffer, "%i", &Num );
pEdit_ei->GetWindowText((LPTSTR) strBuffer,20);
sscanf( strBuffer, "%f", &ei );
// Определение контекстного устройства , с которым связан графический вывод
CWnd* pGraphicRegion = GetDlgItem(IDC_STATIC);
// Создание контекстного устройства для вывода
CClientDC gdc(pGraphicRegion);
// Определение режима отображения координат
gdc.SetMapMode(MM_ANISOTROPIC);
// Определение прямоугольника GraphRect, внутри которого будет выводиться график
CRect GraphRect;
pGraphicRegion->GetClientRect(&GraphRect);
GraphRect.right -= 2; GraphRect.top += 15;
GraphRect.OffsetRect( 1, -1 );
// Заливка области где будет находится график
CBrush SysBrush;
SysBrush.CreateSysColorBrush( COLOR_3DFACE);
gdc.SelectObject( &SysBrush );
gdc.FillRect( GraphRect, &SysBrush );
// Определение области вывода в физических координатах
int xViewportExt = (int)(0.9*GraphRect.Width());
int yViewportExt = (int)(0.9*GraphRect.Height());
gdc.SetViewportExt( xViewportExt, yViewportExt );
int xViewportOrg = (int)(0.09*GraphRect.Width());
int yViewportOrg = (int)(0.97*GraphRect.Height());
gdc.SetViewportOrg( xViewportOrg, yViewportOrg );
// Определение логической системы координат для графика
gdc.SetWindowExt(X_EXT, -Y_EXT) ;
int xWindowOrg = (int)(xMin*X_EXT/(xMax-xMin));
int yWindowOrg = (int)(yMin*Y_EXT/(yMax-yMin));
gdc.SetWindowOrg( xWindowOrg, yWindowOrg );
// Заливка области графика белым цветом
CBrush GraphBrush( RGB(255, 255, 255) );
gdc.SelectObject( &GraphBrush );
GraphRect.SetRect(xWindowOrg,yWindowOrg+Y_EXT,xWindowOrg+X_EXT,yWindowOrg);
gdc.FillRect( GraphRect, &GraphBrush );
// Подготовка пера для рисования линий сетки
CPen penGrid( PS_SOLID, 1, RGB(0, 0, 0) );
gdc.SelectObject(&penGrid);
// Подготовка строкового буфера
char StringBuffer[100];
// Создание и инициализирование шрифта
CFont font;
font.CreatePointFont( (int)(Y_EXT/3),(CString) "Times New Roman" );
// Определение цвета фона для выводимых надписей
gdc.SelectObject( &font );
gdc.SetBkColor( RGB(231,231,231) );
double xVal;
double yVal;
// Цикл для проведений линий сетки и подписей к ним
for(int xPos, yPos, j = 0; j <= GRIDNUM; j++) {
xVal = xMin + j*(xMax-xMin)/GRIDNUM;
xPos = (int)(xVal*X_EXT/(xMax-xMin));
sprintf( strBuffer,"%g", xVal);
gdc.TextOut( xPos - (int)(0.035*X_EXT), (int)((yMin/(yMax-yMin)-0.03)*Y_EXT), (CString) strBuffer );
gdc.MoveTo( xPos, (int)(yMin*Y_EXT/(yMax-yMin)) );
gdc.LineTo( xPos, (int)(yMin*Y_EXT/(yMax-yMin))+Y_EXT );
yVal = yMin + j*(yMax-yMin)/GRIDNUM;
yPos = (int)(yVal*Y_EXT/(yMax-yMin));
sprintf( strBuffer,"%g", yVal);
gdc.TextOut( (int)((xMin/(xMax-xMin)-0.09)*X_EXT), yPos + (int)(0.02*Y_EXT), (CString) strBuffer );
gdc.MoveTo( (int)(xMin*X_EXT/(xMax-xMin)), yPos );
gdc.LineTo((int)(xMin*X_EXT/(xMax-xMin))+X_EXT, yPos );
}
// Отсечение линий, выходящих за границы области графика
gdc.LPtoDP( &GraphRect );
CRgn GraphRgn;
GraphRgn.CreateRectRgnIndirect( &GraphRect );
gdc.SelectClipRgn( &GraphRgn );
// Вычисление массивов значений функций
for(int j = 0; j <= Num; j++) {
x[j] = xMin + j*(xMax-xMin)/Num; // Вычисление значений x
y_integral[j]=integral(1,x[j],ei); // Вычисление значений интегрального представления
y_ryad[j] = r(x[j]); // Вычисление значений разложений в ряд
}
// Установка пера для прорисовки разложений в ряд
CPen penGraph( PS_SOLID, 12, RGB(0, 0, 255) );
gdc.SelectObject(&penGraph);
gdc.MoveTo( (int)(x[0]*X_EXT/(xMax-xMin)), (int)(y_ryad[0]*Y_EXT/(yMax-yMin)) ); // Установка начальной точки
for(int j = 0; j <= Num; j++) {
gdc.LineTo((int)(x[j]*X_EXT/(xMax-xMin)),(int)(y_ryad[j]*Y_EXT/(yMax-yMin))); // Прорисовка линии
}
// Установка пера для прорисовки интегрального представления
CPen penGraph2( PS_SOLID, 6, RGB(255, 0, 0) );
gdc.SelectObject(&penGraph2);
gdc.MoveTo( (int)(x[0]*X_EXT/(xMax-xMin)), (int)(y_integral[0]*Y_EXT/(yMax-yMin)) ); // Установка начальной точки
for(int j = 0; j <= Num; j++) {
gdc.LineTo((int)(x[j]*X_EXT/(xMax-xMin)),(int)(y_integral[j]*Y_EXT/(yMax-yMin))); // Прорисовка линии
}
}
long double Fact(int x) // Функция вичисления факториал
{
long double xx;
xx=1;
for (int i=2; i<=x; i++) {
xx*= i;
}
return xx;
}
long double pows(long double x, long double y)
{
if (x == 0) {
return 0;
} else if (y > 0) {
return pow(x,y);
} else if (y < 0) {
return 1.0/pow(x,y);
} else {
return 1;
}
}
// Интегральное представление
long double f(long double t) // Вичисления функции интеграла
{
if (pows(t * t - 1, (long double)0.5) != 0) {
return 1.0/pows(t * t - 1, (long double)0.5);
} else {
return 0;
}
}
/* Реализация фун – ции, вычисляющей интеграл */
float integral(float a, float b, float e)
{
long double n =2, i; /* Начальное число разбиений */
long double s_ab = f(a) + f(b); /* Сумма значений фун – ции в a и b */
long double h = (b - a) / n; /* Вычисляем шаг */
long double s_k = 0, s_m;
long double s_x = 0, s_x0;
/* Сумма значений фун – ции в нечетных точках */
for (i = 2; i < n; i += 2) {
s_k += f(a + i * h);
}
do {
s_m = 0;
s_x0 = s_x;
/* Сумма значений фун – ции в четных точках */
for (i = 1; i < n; i += 2) {
s_m += f(a + i * h);
}
/* Подсчет результата */
s_x = h / 3 * (s_ab + 2 * s_k + 4 * s_m);
/* Избегаем деления на ноль */
if (s_x == 0) s_x = e;
s_k += s_m;
n *= 2;
h /= 2;
} while (fabs((s_x - s_x0) / 15) > e);/* Выполнять до тех пор, пока результат не будет удовлетворять допустимой ошибке */
return (s_x);
}
long double r(long double x) // Вичисления по разложению в ряд
{
return log(x + pow(x * x -1,(long double)0.5));
}
Графік функції: