Міністерство освіти, науки, молоді та спорту України
Національний університет “Львівська політехніка”
Кафедра ЕОМ
Звіт
до лабораторної роботи №1
з дисципліни: « »
«ВИКОРИСТАННЯ ФУНКЦІОНАЛЬНОЇ ДЕКОМПОЗИЦІЇ ДЛЯ РОЗВ’ЯЗКУ ОБЧИСЛЮВАЛЬНИХ ЗАДАЧ»
Варіант №25
Підготував:
Прийняв:
Львів – 2016
Тема: ВИКОРИСТАННЯ ФУНКЦІОНАЛЬНОЇ ДЕКОМПОЗИЦІЇ ДЛЯ РОЗВ’ЯЗКУ
ОБЧИСЛЮВАЛЬНИХ ЗАДАЧ.
Мета: Вивчити методи декомпозицій задач. Набути навиків розв’язування задач з використанням функціональної декомпозиції.
ЗМІСТ ЗВІТУ
1.Тема, мета, аналіз завдання(згідно варіанту).
2. Схема декомпозиції задачі, коментарі до неї та розрахунок прискорення.
3. Текст програми та результат її роботи на довільному наборі вхідних даних, для розмірності n>3.
4. Висновки.
Аналіз завдання
Завдання:
Номер варіанту
Вираз який треба обчислити
Вектор y1
Вектор y2
Матриця Y3
25
рядок
bi=3i/7+7/3i для парних і
bi=25/i3 для непарних і
b1A1+ (A1c1’)’
A2(B2+C2)
Cij=25/(i+j)3
x=y1'*(Y3+y1'y1*Y3*Y3+y2'y2')+y1'(y1'y1*Y3+Y3*Y3*Y3) – вектор-рядок
Де y1, y2, Y3 обчислюються так:
y1 = A*b, де bi = 3i/7+7/3i - для парних і, bi=25/і3 - для непарних і (i=1,..,n)
y2 = b1A1 +(A1c1’)’
Y3 = A2 (B2 +C2 ) , де Cij =25/(i + j)3
Виконання:
Значення n задаємо з клавіатури, інші дані або вводимо з клавіатури, або генеруються випадковим чином. Елементи матриць A, A1, A2, B2 та векторів b1,c1 є цілими додатними числами, більшими за нуль:
розмірність матриць – n;
матриці A, A1, A2, B2 ;
вектори-рядки b1,c1 .
Елементи вектора-стовпця b та матриця C2 обраховуються згідно своїх індексів, враховуючи розмірність n. Значення їх елементів різко зменшуються зі збільшенням n.
Для обчислень y1, y2, Y3 та кінцевого результату використаємо правила матричних обчислень:
Таблиця 1. Результати добутків в матричних обчисленнях
результатом множення матриці на матрицю є матриця.
cij=
результатом множення матриці на вектор-стовпець є вектор-стовпець.
cj=
результатом множення вектора-рядка на вектор-стовпець є число
с=
результатом множення вектора-стовпця на вектор-рядок є матриця
сij=
результатом множення двох векторів-стовпців є число.
с=
результатом множення вектора-рядка на матрицю на є вектор-рядок.
сj=
Оскільки, згідно правил, добуток не є комутативною операцією, всі множення слід виконувати в тій послідовності, яка задана в формулах.
Під час обчислення y1 результатом множення матриці А на вектор-стовпець b має бути вектор-стовпець, елементами, якого є дійсні числа.
Під час обчислення y2: добуток b1A1 – вектор-рядок на матрицю є вектор-рядок; добуток A1c1’ – матриця на вектор-стовпець (оскільки c1’-це транспонований вектор-рядок, тобто вектор стовпець) є вектор-стовпець, і відповідно (A1c1’)’ – це вектор-рядок. Сума двох векторів-рядків y2=b1A1+(A1c1’)’ є вектор-рядок
При обчисленні Y3 згідно правил (сума двох матриць є матриця, добуток двох матриць є матрицею) отримаємо матрицю з дійсних чисел.
В обчисленні загального виразу приймають участь три різні елементи – вектор-стовпець y1, вектор-рядок y2 та матриця Y3.
Розглянемо поетапно всі рівні декомпозиції задачі.
Етап 2. B2+C2 - матриця. b1*A1 – вектор-рядок. (A1c1’)’ – вектор-рядок.
Етап 3. Y3=A2*(B2+C2) – матриця. y2=b1A1+(A1c1’)’ – вектор-рядок. y1=A*b – вектор-стовпець.
Етап 4. Y3*Y3 – матриця. y1'y1 – число (як результат добутку рядка на стовпець). y2'y2 – матриця (добуток стовпця на рядок).
Етап 5. Y3*Y3*Y3 – матриця (як добуток матриць). y1'y1*Y3*Y3 – матриця (добуток числа на матрицю). y1'y1*Y3 – матриця (добуток числа на матрицю).
Етап 6. y1'y1*Y3*Y3+y2'y2 – матриця (як сума матриць). y1'y1*Y3+Y3*Y3*Y3 – матриця (як сума матриць).
Етап 7. Y3+y1'y1*Y3*Y3+y2'y2' – матриця (як сума трьох матриць). y1'(y1'y1*Y3+Y3*Y3*Y3) – вектор-рядок (як добуток вектора-рядка на матрицю).
Етап 8. y1'*(Y3+y1'y1*Y3*Y3+y2'y2') – вектор-рядок (як добуток вектора-рядка на матрицю).
Етап 9. x=y1'*(Y3+y1'y1*Y3*Y3+y2'y2')+y1'(y1'y1*Y3+Y3*Y3*Y3) – вектор-рядок (як сума двох векторів-рядків).
Схема декомпозиції задачі
Рис.1 Схема декомпозиції обчислення виразу
Оцінимо прискорення, яке можна отримати при реалізації обчислень згідно приведеної схеми. Кількість елементарних операцій на схемі – 26. Кількість етапів обчислення – 9. Отже, максимально можливе прискорення для обчислень по нашій схемі k=26/9=2.889.
Обчислення виразу проводяться з допомогою програми, виконаній на Visual Studio 2012 (віконна форма, графічний інтерфейс). Для обчислень використовується клас matrix, описаний в заголовочному файлі matrix.h. Основна форма – Form1.h. Наведено заголовок та частину коду, в якій здійснюються обчислення:
//Form1.h
#pragma once
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <ctype.h>
#include <fstream>
#include "matrix.h"
#include <Windows.h>
#include <ShellAPI.h>
#include <process.h>
using namespace std;
int n;
double buf;
bool isData=false;
bool isCalc=false;
namespace L2V25KVM {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Сводка для Form1
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: добавьте код конструктора
//
}
protected:
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
***************************************************************
//Кнопка – Ввід даних
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) {
if ((textBox1->Text!="")&&(textBox2->Text!="")){
n=Convert::ToInt32(textBox1->Text);
if(n>3){
//автоматична генерація даних
if(textBox2->Text=="y"){
dataGridView1->Columns->Clear();
dataGridView1->ColumnCount=n;
dataGridView1->RowCount=n;
dataGridView2->Columns->Clear();
dataGridView2->ColumnCount=n;
dataGridView2->RowCount=n;
dataGridView3->Columns->Clear();
dataGridView3->ColumnCount=n;
dataGridView3->RowCount=n;
dataGridView4->Columns->Clear();
dataGridView4->ColumnCount=n;
dataGridView4->RowCount=n;
dataGridView5->Columns->Clear();
dataGridView5->ColumnCount=n;
dataGridView5->RowCount=1;
dataGridView6->Columns->Clear();
dataGridView6->ColumnCount=n;
dataGridView6->RowCount=1;
srand(time(NULL));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
dataGridView1->Rows[i]->Cells[j]->Value=Convert::ToString(rand()%10+1);
dataGridView2->Rows[i]->Cells[j]->Value=Convert::ToString(rand()%10+1);
dataGridView3->Rows[i]->Cells[j]->Value=Convert::ToString(rand()%10+1);
dataGridView4->Rows[i]->Cells[j]->Value=Convert::ToString(rand()%10+1);
}
for(int j=0;j<n;j++){
dataGridView5->Rows[0]->Cells[j]->Value=Convert::ToString(rand()%10+1);
dataGridView6->Rows[0]->Cells[j]->Value=Convert::ToString(rand()%10+1);
}
erIni=false;
}
else{
//ввід даних вручну
if (textBox2->Text=="n"){
dataGridView1->Columns->Clear();
dataGridView1->ColumnCount=n;
dataGridView1->RowCount=n;
dataGridView2->Columns->Clear();
dataGridView2->ColumnCount=n;
dataGridView2->RowCount=n;
dataGridView3->Columns->Clear();
dataGridView3->ColumnCount=n;
dataGridView3->RowCount=n;
dataGridView4->Columns->Clear();
dataGridView4->ColumnCount=n;
dataGridView4->RowCount=n;
dataGridView5->Columns->Clear();
dataGridView5->ColumnCount=n;
dataGridView5->RowCount=1;
dataGridView6->Columns->Clear();
dataGridView6->ColumnCount=n;
dataGridView6->RowCount=1;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
dataGridView1->Rows[i]->Cells[j]->Value=Convert::ToString(1);
dataGridView2->Rows[i]->Cells[j]->Value=Convert::ToString(1);
dataGridView3->Rows[i]->Cells[j]->Value=Convert::ToString(1);
dataGridView4->Rows[i]->Cells[j]->Value=Convert::ToString(1);
}
for(int j=0;j<n;j++){
dataGridView5->Rows[0]->Cells[j]->Value=Convert::ToString(1);
dataGridView6->Rows[0]->Cells[j]->Value=Convert::ToString(1);
}
erIni=false;
}
else{
MessageBox::Show("Виберіть метод наповнення матриць","Помилка вводу даних", MessageBoxButtons::OK,MessageBoxIcon::Exclamation);
erIni=true;
}
}
}
else{
MessageBox::Show("Розмірність матриці повинна бути>3","Помилка вводу даних", MessageBoxButtons::OK,MessageBoxIcon::Exclamation);
}
}
else{
MessageBox::Show("Введіть розмірність та метод наповнення матриць","Помилка вводу даних", MessageBoxButtons::OK,MessageBoxIcon::Exclamation);
}
}
//Кнопка Розрахунок
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
//блок програми для перевірки коректності вводу тільки цифр
int ozn0=0;
int ozNN=1;
int uu=0;
string SSS="";
for(int j=0;j<n;j++){
String^ cell=dataGridView5->Rows[0]->Cells[j]->Value->ToString();
for(int i = 0; i < cell->Length; i++)
SSS=SSS+(char)cell[i];
}
for(int j=0;j<n;j++){
String^ cell=dataGridView6->Rows[0]->Cells[j]->Value->ToString();
for(int i = 0; i < cell->Length; i++)
SSS=SSS+(char)cell[i];
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
String^ cell=dataGridView1->Rows[i]->Cells[j]->Value->ToString();
for(int i = 0; i < cell->Length; i++)
SSS=SSS+(char)cell[i];
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
String^ cell=dataGridView2->Rows[i]->Cells[j]->Value->ToString();
for(int i = 0; i < cell->Length; i++)
SSS=SSS+(char)cell[i];
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
String^ cell=dataGridView3->Rows[i]->Cells[j]->Value->ToString();
for(int i = 0; i < cell->Length; i++)
SSS=SSS+(char)cell[i];
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
String^ cell=dataGridView4->Rows[i]->Cells[j]->Value->ToString();
for(int i = 0; i < cell->Length; i++)
SSS=SSS+(char)cell[i];
}
for (int rr=0;rr<(int)SSS.length();rr++){
if(!isdigit(SSS[rr])){
ozNN=0;
break;
}
}
//завершення блоку програми для перевірки коректності вводу тільки цифр
//блок програми для перевірки умови вводу додатніх чисел
if (ozNN==1){
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
if((Convert::ToInt32(dataGridView1->Rows[i]->Cells[j]->Value)<1)||(Convert::ToInt32(dataGridView2->Rows[i]->Cells[j]->Value)<1)||
(Convert::ToInt32(dataGridView3->Rows[i]->Cells[j]->Value)<1)||(Convert::ToInt32(dataGridView4->Rows[i]->Cells[j]->Value)<1)){
ozn0=1;
break;
}
}
if (ozn0!=1){
for(int j=0;j<n;j++){
if((Convert::ToInt32(dataGridView5->Rows[0]->Cells[j]->Value)<1)||
(Convert::ToInt32(dataGridView6->Rows[0]->Cells[j]->Value)<1)){
ozn0=1;
break;
}
}
}
}
else{
ozn0=1;
}
//завершення блокн програми для перевірки умови вводу додатніх чисел
if(ozn0==0)
isData=true;
else
isData=false;
//блок програми для проведення розрахунків
if (erIni==false)
if (isData){
HANDLE hFile;
hFile = CreateFileA("c:\\labi\\pro-lab1-rezult.txt",GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); //створює новий файл
ff.open("c:\\labi\\pro-lab1-rezult.txt",ios::out);
ff<<"Ця програма обчислює вираз:"<<endl<<endl<<"x=y1'*(Y3+y1'y1*Y3*Y3+y2'y2')+y1'(y1'y1*Y3+Y3*Y3*Y3)"<<endl<<endl;
ff<<"y1=A*b - вектор"<<endl;
ff<<"y2=A1b1'+(A1c1')' - вектор"<<endl;
ff<<"Y3=A2(B2+C2) - матриця"<<endl;
ff<<"Матриці A, A1, A2, B2 та вектори b1 i c1 вводяться з клавіатури або генеруються випадковим чином."<<endl<<endl;
ff<<"================================================================================================="<<endl;
ff<<"Введена розмірність матриць та векторів n="<<n<<endl;
//state 1
ff<<endl<<endl<<"<Етап 1>"<<endl;
Matrix y1(n,1),y2(1,n),Y3(n,n);
Matrix YY2(n,n), mul1(1,n),YY3(n,n),Y3y1(n,1),y1y2t(n,1), YY3y1(n,1), ty1(1,n),ty2(n,1), ty1Y3(1,n);
Matrix C2(n,n),B2(n,n),A2(n,n),b1(1,n),c1(1,n),A1(n,n),b(n,1),A(n,n),st2BC(n,n),st2bc(n,1);
Matrix mulb1A1(1,n), tc1(n,1), A1tc1(n,1),tA1tc1(1,n),tb(1,n),st81(1,n),x(1,n);
Matrix ty1y1(1,1), ty2y2(n,n), st51(n,n), st52(n,n),st61(n,n),st62(n,n),st71(n,n),st72(1,n);
for(int i=0;i<n;i++){
b1.mas[0][i]=Convert::ToDouble(this->dataGridView5->Rows[0]->Cells[i]->Value);
c1.mas[0][i]=Convert::ToDouble(this->dataGridView6->Rows[0]->Cells[i]->Value);
for(int j=0;j<n;j++){
A.mas[i][j]=Convert::ToDouble(this->dataGridView1->Rows[i]->Cells[j]->Value);
A1.mas[i][j]=Convert::ToDouble(this->dataGridView2->Rows[i]->Cells[j]->Value);
A2.mas[i][j]=Convert::ToDouble(this->dataGridView3->Rows[i]->Cells[j]->Value);
B2.mas[i][j]=Convert::ToDouble(this->dataGridView4->Rows[i]->Cells[j]->Value);
String^ cell = dataGridView1->Rows[i]->Cells[j]->Value->ToString();
}
}
for(int i=0;i<n;i++){
int ii=i+1;
for(int j=0;j<n;j++){
int jj=j+1;
buf=(double)25/((ii+jj)*(ii+jj)*(ii+jj));
C2.put(i,j,buf);
}
}
for(int i=0;i<n;i++){
int p=i+1;
b.put(i,0,(double )fmod((double )(p),(double )2)>0 ? (double )25/(p*p*p):(double )3*p/7+7/(3*p));
}
ff<<endl<<"C2"<<endl;
C2.print();
ff<<endl<<"B2"<<endl;
B2.print();
ff<<endl<<"A2"<<endl;
A2.print();
ff<<endl<<"b1"<<endl;
b1.print();
ff<<endl<<"c1"<<endl;
c1.print();
ff<<endl<<"A1"<<endl;
A1.print();
ff<<endl<<"b"<<endl;
b.print();
ff<<endl<<"A"<<endl;
A.print();
// state 2
ff<<endl<<endl<<"<Етап 2>"<<endl;
st2BC.madd(B2,C2);
ff<<endl<<"B2+C2"<<endl;
st2BC.print();
mulb1A1.mmul(b1,A1);
ff<<endl<<"b1*A1"<<endl;
mulb1A1.print();
tc1.transp(c1);
A1tc1.mmul(A1,tc1);
tA1tc1.transp(A1tc1);
ff<<endl<<"(A1c1’)’"<<endl;
tA1tc1.print();
//state 3
ff<<endl<<endl<<"<Етап 3>"<<endl;
Y3.mmul(A2,st2BC);
ff<<endl<<"Y3=A2*(B2+C2)"<<endl;
Y3.print();
y2.madd(mulb1A1,tA1tc1);
ff<<endl<<"y2=b1A1+(A1c1’)’"<<endl;
y2.print();
y1.mmul(A,b);
ff<<endl<<"y1=A*b"<<endl;
y1.print();
//state 4
ff<<endl<<endl<<"<Етап 4>"<<endl;
YY2.mmul(Y3,Y3);
ff<<endl<<"Y3*Y3"<<endl;
YY2.print();
ty1.transp(y1);
ty2.transp(y2);
ty1y1.mmul(ty1,y1);
ty2y2.mmul(ty2,y2);
ff<<endl<<"y1'y1"<<endl;
ty1y1.print();
ff<<endl<<"y2'y2"<<endl;
ty2y2.print();
//state5
ff<<endl<<endl<<"<Етап 5>"<<endl;
YY3.mmul(YY2,Y3);
ff<<endl<<"Y3*Y3*Y3"<<endl;
YY3.print();
st51.mmul(ty1y1,YY2);
st52.mmul(ty1y1,Y3);
ff<<endl<<"y1'y1*Y3*Y3"<<endl;
st51.print();
ff<<endl<<"y1'y1*Y3"<<endl;
st52.print();
//state 6
ff<<endl<<endl<<"<Етап 6>"<<endl;
st61.madd(st51,ty2y2);
st62.madd(st52,YY3);
ff<<endl<<"y1'y1*Y3*Y3+y2'y2"<<endl;
st61.print();
ff<<endl<<"y1'y1*Y3+Y3*Y3*Y3"<<endl;
st61.print();
//state 7
ff<<endl<<endl<<"<Етап 7>"<<endl;
st71.madd(Y3,st61);
st72.mmul(ty1,st62);
ff<<endl<<"Y3+y1'y1*Y3*Y3+y2'y2'"<<endl;
st71.print();
ff<<endl<<"y1'(y1'y1*Y3+Y3*Y3*Y3)"<<endl;
st72.print();
//state 8
ff<<endl<<endl<<"<Етап 8>"<<endl;
st81.mmul(ty1,st71);
ff<<endl<<"y1'*(Y3+y1'y1*Y3*Y3+y2'y2')"<<endl;
st81.print();
//state 9
ff<<endl<<endl<<"<Етап 9>"<<endl;