АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

RedPen(PS_SOLID,1,RGB(255,0,0)),

Читайте также:

    Лабораторная работа № 12-3

    РЕШЕНИЕ АЛГЕБРАИЧЕСКИХ И ТРАНСЦЕНДЕНТНЫХ УРАВНЕНИЙ
    МЕТОДОМ ИТЕРАЦИЙ В СРЕДЕ VISUAL C++

     

    Цель – научиться использовать средства Microsoft Visual C++ для создания MFC-приложений Windows однодокументного типа на примере нахождения приближенного значения корней алгебраического трансцендентного уравнения f(x)=0 методом итераций.

     

    Постановка задачи

    1. С помощью однодокументного MFC-приложения Windows найти приближенное значение корней алгебраического уравнения f(x)=0 методом половинного деления с точностью e.

    2. Сравнить вычисленные значения с полученными ранее решениями другими методами (комбинированным методом) и технологиями (с помощью электронных таблиц MS Excel и MathCad).

     

    Пример:

    Вычислить корни уравнения

    с точностью e =10-5 на предварительно найденных интервалах изоляции [a, b].

     

    Содержание работы

    1. Найдите интервалы изоляции одного из корней уравнения (с помощью электронной таблицы или графически). Действительные корни уравнения принадлежат интервалу, на котором функция меняет знак. Для данного уравнения они следующие: [-2;-1], [0;1], [4;5]. Найдем корень для интервала [-2;-1].

    2. Вычислите для каждого интервала коэффициент l, обеспечивающий устойчивое схождение к корню для интервала [-2;-1]. Вот необходимые соотношения для нахождения l:

           
     
       
     

     


    Проверим знак производной на интервале [-2;-1]: f’ (-2)=17>0; f’ (-1)=2.4>0, значит знаки неравенства для l оставляем.

     

     

    Подставив вместо x соответствующие значения границ интервала изоляции корня, получаем два неравенства:

    x=-2

     
     


    x=-1

     

    Выбираем l, удовлетворяющее обоим неравенствам. Например, l =0.1.

    3. Создать проект однодокументного MFC-приложения, выполняющего пункты задания.

    · Запустить мастер создания проекта AppWizard командой меню File | New | Project.

    · Выделить мышью вариант приложения MFC Application.

    · Перейти в окно редактирования Name и набрать имя создаваемого проекта Lab12.

    · При помощи кнопки «Brouse…» справа от окна редактирования Location перейти на рабочий логический диск (например, R).

    · Подтвердить нажатием кнопки OK выбранные опции панели New Project.

     

    Yj

     

    · В открывшемся следующем окне мастера на вкладке Application Type выбрать переключатель Single document и поменять язык ресурсов Resource language на «Английский».

     

     

    · Подтвердить выбранные опции, нажав Finish.

    4. Мастер ApplicationWizard сгенерирует проект приложения SDI (Single Document Interface), которое можно откомпилировать и запустить на выполнение. Создан ряд классов, название которых основано на имени проекта. Класс CLab12Doc (Документ) отвечает за хранение и обработку данных приложения, а класс CLab12View (Вид) – за отображение Документа на экране.

     

     

    5. Подготовим шаблон диалоговой панели приложения для приема исходных данных.

    · Перейдите в папку проекта ResourceView, раскройте узел проекта, вызовите правой кнопкой мыши на ресурсе Dialog контекстное меню и выполните команду < Insert Dialog> для вставки шаблона новой диалоговой панели в проект.

    · В открывшемся окне редактора диалога появится заготовка панели.

     

     

    · Измените язык диалоговой панели. Правой кнопкой мыши вызовите контекстное меню на идентификаторе ресурса IDD_DIALOG1 и выполните команду Properties.

    · В появившемся диалоге Dialog Properties измените язык с английского на русский. Измените имя идентификатора на IDD_DIALOG_INPUT.

     

     

    · Закройте панель свойств, и вы увидите новое имя ресурса в папке диалогов.

     

     

    · Оставьте на диалоговой панели кнопки OK (будет означать согласие с введенными данными) и Cancel (будет отменять ввод данных); добавьте четыре поля редактирования Edit Control для ввода интервала изоляции корня [ a, b ], коэффициента l и точности расчета e; добавьте четыре компоненты Static Text для поясняющих строк.

    · Переименуйте заголовок панели приложения на Ввод исходных данных, а также измените поясняющие строки, откорректировав свойства Caption на панели Properties..

     

     

    · Присвойте элементам управления (кроме надписей) соответствующие идентификаторы:

     

    Элемент управления Назначение Идентификатор
    Поле редактирования Левая граница интервала изоляции корня a IDC_EDIT_A
    Поле редактирования Правая граница интервала изоляции корня b IDC_EDIT_B
    Поле редактирования Точность вычислений e IDC_EDIT_EPS
    Поле редактирования Коэффициент l IDC_EDIT_LAMBDA

    · Добавьте в проект класс для созданного диалога. Выполните двойной щелчок левой мыши по диалоговой панели. Появится окно мастера нового класса. Дайте имя класса CDlgInput в окне Class Name и измените базовый класс Base class на CDialog.

     

     

    · Подтвердите введенные данные, нажав Finish. Вызовите мастера добавления в класс диалога переменных, связанных с окнами редактирования.

    · мастере классов ClassWizard добавьте переменные m_a, m_b, m_eps, m_lambda вещественного типа в класс диалоговой панели CDlgInput для соответствующих введенных данных расчета (a, b, e, l). Соглашайтесь с работой мастера, нажимая кнопку Finish.

     

     

    · На вкладке ClassView вы увидите работу мастера.

     

     

    6. Перейдите на вкладку ResourceView, раскройте дерево классов Lab12 classes, раскройте узел Menu и вызовите редактор меню, выполнив двойной щелчок по идентификатору меню IDR_MAINFRAME. Измените язык ресурса меню на «Русский» с помощью панели свойств

     

     

    · Удалите все пункты меню кроме View и Help. Для этого надо выделить пункт меню и нажать клавишу Delete на соответствующем удаляемом пункте меню.

     

     

    · В пустом пункте меню Type Here нашего приложения введите заголовок пункта меню &Calculation. Измените флажок выпадающего меню Pop-up на False

     

    · введите справочную информацию в поле подсказки Prompt, часть которой «Расчет корня» которая будет появляться в статус-строке выполняющегося приложения при выделении пункта меню. Вторая часть «Расчет» будет возникать во всплывающем окне под соответствующей инструментальной кнопкой во время движения курсора мыши над кнопкой. Идентификатор ID будет добавлен по умолчанию ID_CALCULATION.

     

     

    7. Введите в класс CLab12Doc в качестве открытых членов соответствующие переменные для исходных данных и результатов расчета. Для этого можно использовать мастер добавления переменных Add Variable.

     

     

    8. Добавьте вещественные double переменные a, b, eps, lambda, koren и строку StringData типа CString (результирующая текстовая информация о корне) в класс Документа CLab12Doc.

     

     

    9. Они появятся на вкладке классов.

     

     

    10. Проинициализируйте их в функции OnNewDocument ().

     

    BOOL CLab12Doc::OnNewDocument()

    {

    if (!CDocument::OnNewDocument())

    return FALSE;

     

    // TODO: add reinitialization code here

    // (SDI documents will reuse this document)

    a=-2;

    b=-1;

    eps=1e-5;

    lambda=0.1;

    StringData="";

     

    return TRUE;

    }

    11. Добавим в Документ открытый метод F() для вычисления значения заданной функции f(x).

    · Правой кнопкой мыши на имени класса CLab12Doc вызовите контекстное меню и выполните команду Add Member Function.

     

     

    · В диалоге заполните соответствующие поля мастера функций и нажмите Finish.

     

    · Откройте в редакторе заготовку добавленного метода и вставьте код вычисления значения заданной функции

    double CLab12Doc::F(double x)

    {

    return pow(x,3)-2.8*pow(x,2)-6.2*x+3.7;

    }

    12. Аналогично добавьте в класс Документа CLab12Doc метод Method(), который будет вычислять корень koren на заданном интервале изоляции [ a, b ] с точностью e.

     

    13. В редакторе подкорректируйте код новой функции в соответствии с алгоритмом метода половинного деления.

     

    double CLab12Doc::Method()

    {

    Double

    Xnew, // новое значение Х

    Xold; // значение Х на предыдущей итерации

    Xnew=(a+b)/2; // начальное значение Х

    do

    {

    Xold= Xnew; // переназначение Х для следующей итерации

    Xnew= Xold - lambda*F(Xold); // новая итерация по Х

    }while(fabs(Xnew - Xold)>eps); // проверка на завершение поиска корня

    koren=(Xnew + Xold)/2; // приближенное значение корня

    return koren; // возврат результата

    }

     

    14. Добавьте в класс вида CLab12View метод, реагирующий на нажатие пункта меню Calculation c идентификатором ID_CALCULATION.

    · Вызовите мастер создания обработчика сообщения Windows выполнения команды меню Calculation с помощью контекстного меню в редакторе меню

    · В окне Message type выделите сообщение COMMAND, а в окне Class list выделите имя класса Вида CLab12View и нажмите кнопку Add and Edit для редактирования обработчика.

     

     

    · Откроется редактор текста вновь добавленной функции.

     

     

    · В открывшейся в текстовом редакторе заготовке метода вместо комментария //TODO добавьте соответствующий код для вычисления корня уравнения с точностью e:

     

    void CLab12View::OnCalculation()

    {

    CLab12Doc* pDoc=GetDocument(); // получаем указатель на Документ

    CDlgInput dlg; // объявление переменной диалога данных

    dlg.m_a=pDoc->a; // присвоение переменным диалога значений Документа

    dlg.m_b=pDoc->b;

    dlg.m_eps=pDoc->eps;

    dlg.m_lambda =pDoc->lambda;

    INT_PTR result=dlg.DoModal(); // запуск диалоговой панели данных

    if(result==IDOK) // если завершили диалог нажатием ОК

    { pDoc->a=dlg.m_a; // присвоение переменным Документа значений диалога

    pDoc->b=dlg.m_b;

    pDoc->eps=dlg.m_eps;

    pDoc-> lambda =dlg.m_lambda;

    pDoc->Method(); // вызов метода итераций

    // заполнение строки с результатами расчета

    pDoc->StringData.Format("В диапазоне [%4.1f,%4.1f] корень равен =%9.5f",

    pDoc->a,pDoc->b,pDoc->koren);

    Invalidate(); // требование перерисовки окна Вида

    }

    else // если завершили диалог нажатием CANCEL

    MessageBox("Повторите ввод данных","Внимание!", MB_OK|MB_ICONEXCLAMATION);

     

     

    }

     

    15. Добавьте в начало файла реализации класса вида Lab12View.cpp ссылку на заголовочный файл диалога DlgInput.h.

     

    // Lab12View.cpp: implementation of the CLab12View class

    //

    #include "stdafx.h"

    #include "Lab12.h"

     

    #include "Lab12Doc.h"

    #include "Lab12View.h"

    #include "DlgInput.h"

     

    16. В методе OnDraw() класса Вида CLab12View, который запускается при перерисовке окна, вставьте вывод результирующей строки StringData на экран, начиная с точки с координатами (5,5).

     

    /////////////////////////////////////////////////////////////////////////////

    // CLab12View drawing

     

    void CLab12View::OnDraw(CDC* pDC)

    {

    CLab12Doc* pDoc = GetDocument();

    ASSERT_VALID(pDoc);

    if (!pDoc)

    return;

    // TODO: add draw code for native data here

    pDC->TextOut(5,5,pDoc->StringData);

    }

     

    17. Не забудьте добавить заголовочный файл < math.h > в файл stdafx.h для вызова математических функций.

    18. Войдите в ресурс инструментальных кнопок ToolBar в папке ResourceView.

     

     

    19. Удалите все инструментальные кнопки, кроме справочной и пустой. Удаление происходит, если курсором мыши «перетащить» кнопку за пределы строки кнопок.

     

     

    20. С помощью панели рисования отредактируйте новую инструментальную кнопку, которая будет дублировать выполнение команды меню Calculation.

    · С помощью редактора изображений Image Editor (все инструментальные панели можно отобразить или выключить с помощью команды меню View | Toolbars) нанесем изображение на инструментальную кнопку. Свяжем кнопку с командой меню. В списке идентификаторов ID найдите и выберите идентификатор пункта меню, который мы ввели ранее ID_CALCULATION.

     

     

    21. Откомпилируйте проект и запустите на выполнение. Появится форма приложения с меню, статус-строкой и пустым окном Вида. Задержите курсор мыши над спроектированной инструментальной кнопкой. Вы увидите всплывающее окно подсказки и справку в статус-строке внизу окна приложения. Это информация, введенная вами в панели свойств меню.

     

     

    22. Нажмите пункт меню Calculation. Появляется панель исходных данных. Введите интервал изоляции и точность и нажмите ОК.

     

    23. Результаты расчета появятся в окне Вида.

     

     

    24. Добавим изображение графика заданной функции в окне Вида.

      • Скопируем в папку проекта файлы Graph.h и Graph.cpp класса CGraph, разработанного для рисования графика.
      • Добавим эти файлы в проект командой Project|Add Existing Item…

      • В открывшемся окне мастера добавления файлов выделите имена добавляемых файлов и нажмите кнопку Open

     

      • Файлы появятся в окне проекта Solution Explorer

      • Включим в заголовочный файл Документа перед объявлением класса Документа заголовочный файл Graph.h:

     

    // Lab12Doc.h: interface of the CLab12Doc class

    //

    #include "Graph.h"

    class CLab12Doc: public CDocument

    {

      • Для поддержки библиотеки шаблонов в файл stdafx.h подключим необходимый заголовочный файл:

    #include <math.h>

    #include <afxtempl.h>

      • В функцию рисования Вида добавим код для отображения графика

     

    void CLab12View::OnDraw(CDC* pDC)

    {

    CLab12Doc* pDoc = GetDocument();

    ASSERT_VALID(pDoc);

    // TODO: add draw code for native data here

    pDC->TextOut(5,5,pDoc->StringData);

    // Вычисляем точки графика

    pDoc->Calc();

    // Выясняем размеры массивов

    UINT size = (pDoc->xGr).GetSize();

    CRect r;

    GetClientRect(r); // Выясняем размеры окна Вид

    // Создаем объект импортированного класса

    CGraph graph(r, size);

    // Выбираем черное перо, запоминая текущее

    CPen* pOldPen = pDC->SelectObject (&BlackPen);

    // Задаем надписи для осей

    CString Xlab("t"), Ylab("y");

    // Просим изобразить сетку

    graph.DrawGrid (pDC, pDoc->sCurFunc, Xlab,Ylab, pDoc->xGr, pDoc->yGr);

    // Открепляем перо Windows от объекта класса

    BlackPen.Detach();

    // Выбираем синее перо

    pDC->SelectObject (&BluePen);

    // Просим изобразить кривую графика

    graph.DrawFunc (pDC);

    // Реставрируем перо Windows

    pDC->SelectObject (pOldPen);

    }

      • В класс Документа добавим функцию Calc() для вычисления массива отображаемых точек:

     

      • В заготовку этого метода добавьте следующий код:

     

    void CLab12Doc::Calc()

    {

    UINT i;

    NPoints = 201;

    xGr.SetSize (NPoints); // Отводим память

    yGr.SetSize (NPoints);

    sCurFunc.Format("Function F(x)");

    double dx=(X2-X1)/(NPoints-1);

    for(i=0;i<NPoints;i++)

    {

    xGr[i]=X1+i*dx;

    yGr[i]=F(xGr[i]);

    }

    Time=X2-X1; // интервал аргумента

    }

      • В public-сектор класса Документа вставьте объявление переменных:

     

    class CLab12Doc: public CDocument

    {

    protected: // create from serialization only

    CLab12Doc();

    DECLARE_DYNCREATE(CLab12Doc)

    // Attributes

    public:

    TValues xGr, yGr; // Массивы абсцисс и ординат

    UINT NPoints; // Количество точек

    CString sCurFunc; // Заголовок текущего графика функции

    double Time; // Диапазон изменения координаты X

    TData data; // Обобщенные параметры функций

    double X2,X1; // Диапазон Х изображения графика

      • Добавьте инициализацию для границ изображения графика [X1, X2]:

     

    BOOL CLab12Doc::OnNewDocument()

    {

    if (!CDocument::OnNewDocument())

    return FALSE;

     

    // TODO: add reinitialization code here

    // (SDI documents will reuse this document)

    a=-2;

    b=-1;

    eps=1e-5;

    lambda=0.1;

    StringData="";

    X1=-3.0;

    X2=5.0;

    return TRUE;

    }

      • В объявление класса Вид добавьте переменные для пера рисования:

     

    class CLab12View: public CView

    {

    protected: // create from serialization only

    CLab12View();

    DECLARE_DYNCREATE(CLab12View)

     

    // Attributes

    public:

    CLab12Doc* GetDocument() const;

    CPen BlackPen, BluePen, RedPen;

      • Инициализируем перья в конструкторе Вида:

     

    CLab12View::CLab12View()

    :BlackPen(PS_SOLID,1,RGB(0,0,0)),

    RedPen(PS_SOLID,1,RGB(255,0,0)),


    Поиск по сайту:



    Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.052 сек.)