Программа для вычислений над матрицами
Содержание
Введение
.
Матрицы
.1
Основные действия над матрицами
.
Вектор
.1
Умножение вектора на матрицу
.
Классы
.1
Конструкторы и деструкторы
.2
Перегрузка операций
.3
Дружественные функции
.4
Неявный указатель this
.5
Код программы
.6
Результаты
.7
Проверка результатов в Mathcad
Список
литературы
Введение
На сегодняшний день математическое
программирование - важная составляющая всего программирования. Большие и
сложные вычисления благодаря простым программам становятся простыми.
В данной курсовой работе создавалась программа
для вычислений над матрицами.
В качестве среды программирования выбрана MS
Visual Studio 2008 и язык программирования C++.
1. Матрицы
Матрицей размерности называется
прямоугольная таблица чисел , где ,
:
расположенных в m строках и n столбцах. Матрица
называется квадратной, если .
.1 Основные действия над матрицами
Сложение и вычитание матриц сводится к
соответствующим операциям над их элементами. Самым главным свойством этих
операций является то, что они определены только для матриц одинакового размера.
Таким образом, возможно определить операции сложения матриц:
Суммой матриц является матрица, элементами
которой являются соответственно сумма элементов исходных матриц.
Операция умножения матрицы любого размера на
произвольное число сводится к умножению каждого элемента матрицы на это число.
Транспонирование матрицы
<#"607734.files/image009.gif">
Если A - матрица размера , то AT -
матрица размера .
Умножение матриц
<#"607734.files/image011.gif">
В первом множителе должно быть
столько же столбцов, сколько строк во втором. Если матрица A имеет размерность , B - , то
размерность их произведения AB = C есть .
2. Вектор
Если матрица состоит только из одного столбца или
строки, то такой объект называется вектором. Размерностью вектора называется
число его элементов.
.1 Умножение вектора на матрицу
Если имеется некоторая матрица А размерностью и
некоторый вектор B размерностью n, то при умножении получаем вектор С
размерностью m.
В результате умножения матрицы на вектор будем
иметь матрицу-столбец, у которой количество строк равно количеству строк
исходной матрицы.
В результате умножения вектора на матрицу будем
иметь матрицу-строку, у которой количество столбцов равно количеству столбцов
исходной матрицы.
3. Классы
Класс - это тип структуры, позволяющий включать
в описание типа не только элементы данных, но и функции (функции-элементы или
методы).
Для ограничения доступа к элементам класса
используются следующие спецификаторы доступа:ограничений доступа нет;доступны
только в порожденных классах;доступны только в своем классе.
.1 Конструкторы и деструкторы
Добавим в класс функцию
Matrix(int m, int n)
Такая функция называется конструктором и служит
для инициализации создаваемого объекта данных. Имя конструктора должно
совпадать с именем класса, конструктор н должен возвращать значений и содержать
оператор return. Тип его явно не описывается. Конструктор может быть
перегружен, поэтому у любого нового типа данных могут быть несколько
конструкторов.
~Matrix() - специальный оператор, который
называется деструктором. Он необходим для того, чтобы корректно завершить
существование нашего объекта, то есть освободить память в куче.
Деструктор, как и конструктор, не должен возвращать
значение и иметь явное описание типа. В отличие от конструкторов, которых может
быть несколько у одного и того же класса, деструктор должен быть один и не
должен иметь аргументов.(const Matrix &A) называется конструктором копий.
Он используется при создании объекта с инициализацией его объектом того же
типа.
Кроме того, конструктор копии используется при
инициализации формального параметра функции в случае передачи ей объекта по
значению, и при возврате объекта из функции по оператору return. При передаче
ссылок и указателей конструктор копии не используется.
Неявный конструктор копии обеспечивает простое
поэлементное копирование одного объекта во второй. Такой вид копирования часто
называют поверхностным.
.2 Перегрузка операций
Большинство операций языка С++ для новых типов
данных может быть перегружено. Для перегрузки операции необходимо создать
функцию с названием, состоящим из ключевого слова operator и знака
перегружаемой операции. Количество параметров этой функции определяется тем,
одноместная или двухместная операция перегружается, а также наличием неявных
элементов у методов класса.
Перегрузка операций предполагает введение в язык
двух взаимосвязанных особенностей: возможности объявлять в одной области
видимости несколько процедур или функций с одинаковыми именами и возможности
описывать собственные реализации операций.
Например, чтобы перегрузить оператор сложения,
нужно определить функцию с именем operator+.
Операторные функции перегруженных операторов, за
исключением new и delete, должны подчиняться следующим правилам:
операторная функция должна быть либо
нестатической фенкцией-членом класса, либо принимать аргумент типа класса или
перечислимого типа, или аргумент, который является ссылкой на тип класса или
перечислимый тип;
операторная функция не может изменять число
аргументов или приоритеты операторов и порядок их выполнения по сравнению с
использованием соответствующео оператора для встроенных типов данных;
операторная функция унарного оператора,
объявленная как функция-член, не должна иметь параметров; если же она объявлена
как глобальная функция, она должна иметь один параметр;
операторная функция не может иметь параметры по
умолчанию и др.
.3 Дружественные функции
Согласно концепции инкапсуляции данных С++
функция, не являющаяся членом класса, не может получить доступ к его закрытым
(private) элементам.
В языке С++ реализована возможность обойти
данное ограничение с помощью друзей. С++ позволяет объявить 2 вида друзей
класса: дружественную функцию или дружественный класс.
Дружественные функции не являются членами
класса, но тем не менее имеют доступ к его закрытым членам. Более того, одна
такая функция может иметь доступ к закрытым членам нескольких классов.
Чтобы объявить функцию дружественной некоторому
классу, в определение этого класса включают ее прототип, перед которым ставится
ключевое слово friend.
friend ostream&
operator<<(ostream& os, const Matrix& A)
Дружественная функция не является членом класса,
в котором она объявлена. Поэтому, вызывая дружественную функцию, не нужно указывать
имя объекта или указатель на объект и операцию доступа к члену класса (точку
или стрелку). Доступ к закрытым членам класса дружественная функция получает
только через объект класса, который в силу этого должен быть либо объявлен
внутри функции, либо передан ей в качестве аргумента.
Функция может быть дружественна сразу нескольким
классам.
Каждый метод класса содержит в качестве данного
следующий указатель, передаваемый при вызове метода в качестве параметра:
имя_типа *this;
Этот указатель представляет собой адрес
конкретного объекта, для которого был вызван метод.
Использовать указатель this для доступа к
элементам класса можно, но вряд ли целесообразно, поскольку это и так
подразумевается по умолчанию. Явно использовать this необходимо только в тех
случаях, когда требуется работа непосредственно с адресами объектов, например,
при организации динамических структур данных.
Создадим программу, которая будет реализовывать
работу с классом Matrix.
.5 Код программы
#include "stdafx.h"
#include <iostream>
#include "conio.h"
#include "math.h"
#include "time.h"
using namespace std;
// КЛАСС
MATRIXMatrix
{:
double** M;m;// число строкn;// число столбцов:
// конструктор по умолчанию();
// конструктор(int m, int n);
// конструктор копий(const Matrix &A);
// заполнение матрицы случайными
числамиSetMatrix();
// перегрузка оператора присваивания&
operator=(Matrix &A);
// перегрузка оператора сложенияoperator+(Matrix
&);
// перегрузка оператора умножения на
числоoperator*(const int &);
// умножение матрицы на матрицуoperator*(Matrix
&);
// транспонирование матрицы& operator^(const
Matrix &);
// перегрузка оператора вывода в поток
friend ostream&
operator<<(ostream& os, const Matrix& A);
// деструктор
~Matrix();
};
// КЛАСС
VECTORVector
{*v;n;:
// конструктор(int n);
// конструктор копий
Vector(const Vector &a);
// деструктор
~Vector();
// заполнение вектора случайными
числамиSetVector();
// перегрузка оператора присваивания&
operator=(Vector &a);
// перегрузка
оператора
вывода
в
потокostream&
operator<<(ostream& os, const Vector& a);
// умножение вектора на матрицуoperator*(const
Matrix &A);
};
// Конструктор по умолчанию::Matrix()
{= NULL;
}
// Конструктор::Matrix(int _m, int _n)
{= _m;= _n;
M = new double*[m];
for (int i = 0; i < m; i++)
M[i] = new double[n];
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
{
M[i][j] = 0;
}
}
// Конструктор
копий::Matrix(const
Matrix &A)
{= A.m;= A.n;= new double*[m];(int i
= 0; i < m; i++)[i] = new double[n];
(int i = 0; i < m; i++)(int j =
0; j < n; j++)
{[i][j]=A.M[i][j];
}
}
// Заполнение матрицы случайными числами
void Matrix::SetMatrix()
{(int i = 0; i < m; i++)
{(int j = 0; j < n; j++)
{[i][j]=(double)((rand()%200)-100.0);
}
}
}
// Перегрузка
оператора
присваивания&
Matrix::operator =(Matrix &A)
{(int i = 0; i < m; i++)
{[] M[i];
}[] M;
}= new double*[m];(int i = 0; i <
m; i++)[i] = new double[n];
= A.m;= A.n;(int i = 0; i < m;
i++)(int j = 0; j < n; j++)[i][j] = A.M[i][j];*this;
}
// Сложение
матрицMatrix::operator+(Matrix
&A)
{temp(m, n);(n!=A.n || m!=A.m)
{<<"Сложение матриц
невозможно.\n"
"Не совпадают размерности!\n"
"Программа завершила работу.\n";
exit(0);
}
{(int i = 0; i < m; i++)(int j =
0; j < n; j++).M[i][j] = M[i][j] + A.M[i][j];
return temp;
}
}
// Умножение матрицы на число
Matrix Matrix::operator*(const int
&k)
{temp(m, n);(int i = 0; i < m;
i++)(int j = 0; j < n; j++).M[i][j] = M[i][j]*k;
return temp;
}
// Умножение матрицы на матрицу
Matrix Matrix::operator*(Matrix
&A)
{temp(m, A.n);(int i = 0; i < m;
i++)
{(int j = 0; j < n; j++).M[i][j]
= 0;
}(n!=A.m)
{<<"Умножение матриц
невозможно.\n"
"Не совпадают размерности!\n"
"Программа завершила работу.\n";
exit(0);
}
{(int i = 0; i < m; i++)(int j =
0; j < n; j++)(int k = 0; k < A.n; k++).M[i][k] += M[i][j] * A.M[j][k];
}temp;
}
// Транспонирование
матрицы&
Matrix::operator ^(const Matrix &A)
{= A.m;= A.n;(int i = 0; i < m;
i++)(int j = 0; j < n; j++)
{[i][j] = A.M[j][i];
}*this;
}
// Деструктор::~Matrix()
{(int i = 0; i < m; i++)
{[] M[i];
}[] M;
}
// Операция
вывода&
operator<<(ostream& os, const Matrix& A)
{<<'\n';(int i = 0; i <
A.m; i++)
{(int j = 0; j < A.n;
j++)<<A.M[i][j]<<"\t";<<'\n';
}os;
}
// Конструктор
::Vector(int _n)
{= _n;= new double[n];
}
// Конструктор
копий::Vector(const
Vector &a)
{= a.n;= new double[n];(int i = 0; i
< n; i++)
v[i] = a.v[i];
}
// Деструктор::~Vector()
{[] v;
}
// Заполнение вектора случайными числами
void Vector::SetVector()
{= new double[n];(int i = 0; i <
n; i++)
{[i]=(double)((rand()%200)-100.0);
}
}
// Перегрузка оператора присваивания
Vector& Vector::operator
=(Vector &a)
{= a.n;(int i = 0; i < n; i++)[i]
= a.v[i];*this;
}
{ temp (A.n);(int i=0; i< A.n;
i++).v[i]=0;
(int i = 0; i < A.m ; i++)(int j
= 0; j < A.n; j++).v[j] += v[i]*A.M[i][j];temp;
}
// Операция
вывода&
operator<<(ostream& os, const Vector& a)
{<<'\n';(int i = 0; i <
a.n; i++)
{<<a.v[i]<<"
";<<' ';
}<<'\n';os;
}_tmain(int argc, _TCHAR* argv[])
{(LC_CTYPE,
"Russian_Russia.1251");((unsigned)time(NULL));A(3,3),B(3,3),C(3,3),D(3,3),
E(3,3), F(3,3), G(4,2), I(2,6),
H(4,6);v(3),s(3);.SetMatrix();.SetMatrix();.SetMatrix();.SetMatrix();.SetVector();<<endl<<"Матрица
А:"<<endl;<<A;<<endl<<"Матрица
B:"<<endl;<<B;= A + B;<<endl<<"Матрица
C=A+B:"<<endl;<<C;= C*3;<<endl<<"Матрица
D=C*3:"<<endl;<<D;= A*B;<<endl<<"Матрица
E=A*B:"<<endl;<<E;^A;<<endl<<"Матрица
F=At:"<<endl;<<F;<<endl<<"Матрица
G:"<<endl;<<G;<<endl<<"Матрица
I:"<<endl;<<I;=G*I;<<endl<<"Матрица
H=G*I:"<<endl;<<H;<<endl<<"Вектор
v:"<<endl;<<v;=v*A;<<endl<<"Вектор
s=v*A:"<<endl;
cout<<s;0;
}
.6 Результаты
3.7 Проверка результатов в Mathcad
программа матрица класс вектор
Список литературы
Бьeрн
Страуструп. Справочное руководство по C++, 1995
Глушаков
С.В. Программирование на С++, изд.2-е, доп. и переработ. - М.:АСТ, 2008. - 685
с.
Харви
Дейтел, Пол Дейтел. Как программировать на С. - Бином-Пресс, 2008. - 1024 с.