Скачиваний:
26
Добавлен:
01.05.2014
Размер:
7.95 Кб
Скачать
/*  Project first

		Copyright © 1997 by US. All Rights Reserved.

		SUBSYSTEM:    first.exe Application
		FILE:         firstapp.cpp
		AUTHOR:       US


		OVERVIEW
		========
		Source file for implementation of TVector and TMatrix.
*/

#include <windows.h>
#pragma hdrstop

#include <math.h>
#include <values.h>
#include "matrix.h"


// /V\
// |E|
// |C|
// |T|
// |O|
// |R|
// \S/

TVector::TVector(unsigned _length) :
	length(_length),
	data(new double[_length])
{
}
TVector::~TVector()
{
	if (data)
		delete data;
}

double &TVector::operator[] (unsigned y)
{
	static double error = MINDOUBLE;

	if (y < length)
		return data[y];
	else
	{
		::MessageBox(NULL, "Обращение к несуществующему элементу", "TVector::Внутренняя ошибка", MB_OK|MB_ICONSTOP);
		error = MINDOUBLE;
		return error;
	}
}

TVector &TVector::operator+ (TVector &b)
{
	if (length != b.length)
	{
		::MessageBox(NULL, "Сложение векторов разных размеров", "TVector::Внутренняя ошибка", MB_OK|MB_ICONSTOP);
		return *new TVector(0);
	}

	TVector *result = new TVector(length);
	for (unsigned i = 0; i < length; i++)
		result->data[i] = data[i] + b.data[i];

	return *result;
}
TVector &TVector::operator- (TVector &b)
{
	if (length != b.length)
	{
		::MessageBox(NULL, "Вычитание векторов разных размеров", "TVector::Внутренняя ошибка", MB_OK|MB_ICONSTOP);
		return *new TVector(0);
	}

	TVector *result = new TVector(length);
	for (unsigned i = 0; i < length; i++)
		result->data[i] = data[i] - b.data[i];

	return *result;
}
double TVector::operator* (TVector &b)
{
	if (length != b.length)
	{
		::MessageBox(NULL, "Умножение векторов разных размеров", "TVector::Внутренняя ошибка", MB_OK|MB_ICONSTOP);
		return MINDOUBLE;
	}

	double result = 0;
	for (unsigned i = 0; i < length; i++)
		result += data[i] * b.data[i];

	return result;
}

TVector &TVector::operator* (double a)
{
	TVector *result = new TVector(length);

	for (unsigned i = 0; i < length; i++)
		result->data[i] = data[i] * a;

	return *result;
}

void TVector::operator= (TVector &source)
{
	if (length != source.length)
		resize(source.length);

	for (unsigned i = 0; i < length; i++)
		data[i] = source.data[i];
}

void TVector::zero(void)
{
	for (unsigned y = 0; y < length; y++)
		data[y] = 0;
}

int TVector::resize(unsigned _length)
{
	if (length == _length)
		return 1;

	if (data)
		delete data;

	if (!(data = new double[length = _length]))
	{
		::MessageBox(NULL, "resize: Нехватка памяти", "TVector::Ошибка", MB_OK|MB_ICONSTOP);
		length = 0;
		return 0;
	}

	return 1;
}

void TVector::write(FILE *outf)
{
	for (unsigned x = 0; x < length; x++)
	{
		fprintf(outf, "%8.5lf", data[x]);
		if (x < length - 1)
			fprintf(outf, "\t");
	}
}

double TVector::getmax(void)
{
	double result = 0;

	for (unsigned x = 0; x < length; x++)
		if (result < fabs(data[x]))
			result = fabs(data[x]);

	return result;
}

// / M . A . T \
// | .   .   . |
// | R . I . C |
// | .   .   . |
// \ E . S . . /

TMatrix::TMatrix(unsigned _width, unsigned _height) :
	width(_width), height(_height),
	data(new PVector[_width])
{
	for (unsigned i = 0; i < width; i++)
		data[i] = new TVector(_height);
}
TMatrix::~TMatrix()
{
	for (unsigned i = 0; i < width; i++)
		delete data[i];
	delete data;
}

TVector &TMatrix::operator[] (unsigned x)
{
	static TVector error(0);

	if (x < width)
		return *data[x];
	else
	{
		::MessageBox(NULL, "Обращение к несуществующему элементу", "TMatrix::Внутренняя ошибка", MB_OK|MB_ICONSTOP);
		return error;
	}
}

TVector &TMatrix::operator() (unsigned y)
{
	TVector *result = new TVector(width);

	for (unsigned i = 0; i < width; i++)
		result->data[i] = operator[] (i)[y];

	return *result;
}


TMatrix &TMatrix::operator+ (TMatrix &b)
{
	if (width != b.width || height != b.height)
	{
		::MessageBox(NULL, "Сложение матриц разных размеров", "TMatrix::Внутренняя ошибка", MB_OK|MB_ICONSTOP);
		return *new TMatrix(0, 0);
	}

	TMatrix *result = new TMatrix(width, height);
	for (unsigned i = 0; i < width; i++)
		*result->data[i] = *data[i] + *b.data[i];

	return *result;
}

TMatrix &TMatrix::operator- (TMatrix &b)
{
	if (width != b.width || height != b.height)
	{
		::MessageBox(NULL, "Вычитание матриц разных размеров", "TMatrix::Внутренняя ошибка", MB_OK|MB_ICONSTOP);
		return *new TMatrix(0, 0);
	}

	TMatrix *result = new TMatrix(width, height);
	for (unsigned i = 0; i < width; i++)
		*result->data[i] = *data[i] - *b.data[i];

	return *result;
}

TMatrix &TMatrix::operator* (TMatrix &b)
{
	if (width != b.height)
	{
		::MessageBox(NULL, "Умножение матриц разных размеров (a.w!=b.h)", "TMatrix::Внутренняя ошибка", MB_OK|MB_ICONSTOP);
		return *new TMatrix(0, 0);
	}

	TMatrix *result = new TMatrix(b.width, height);
	for (unsigned x = 0; x < b.width; x++)
		for (unsigned y = 0; y < height; y++)
			(*result)[x][y] = operator() (y) * b[x];

	return *result;
}

TMatrix &TMatrix::operator* (double a)
{
	TMatrix *result = new TMatrix(width, height);

	for (unsigned x = 0; x < width; x++)
		for (unsigned y = 0; y < height; y++)
			(*result)[x][y] = operator[] (x) [y] * a;

	return *result;
}


void TMatrix::operator= (TMatrix &source)
{
	unsigned i;

	if (width != source.width || height != source.height)
		resize(source.width, source.height);

	for (i = 0; i < width; i++)
		*data[i] = *source.data[i];
}

TMatrix &TMatrix::operator~ (void)
{
	TMatrix *result = new TMatrix(height, width);

	for (unsigned x = 0; x < width; x++)
		for (unsigned y = 0; y < height; y++)
			(*result)[y][x] = operator[] (x)[y];

	return *result;
}

void TMatrix::zero(void)
{
	for (unsigned x = 0; x < width; x++)
		data[x]->zero();
}

TMatrix &TMatrix::operator! (void)
{
	if (width != height || (width != 2 && width != 1))
	{
		::MessageBox(NULL, "Возведение в -1 степень реализовано только для матриц 2x2 и 1x1", "TMatrix::Внутренняя ошибка", MB_OK|MB_ICONSTOP);
		return *new TMatrix(0, 0);
	}

	TMatrix *result = new TMatrix(width, height);

	if (width == 1)
	{
		(*result)[0][0] = 1 / operator[] (0)[0];
	}
	else
	{
		double det = (operator[] (0)[0]) * (operator[] (1)[1]) - (operator[] (0)[1]) * (operator[] (1)[0]);

		(*result)[0][0] = operator[] (1)[1] / det;
		(*result)[0][1] = - operator[] (1)[0] / det;
		(*result)[1][0] = - operator[] (0)[1] / det;
		(*result)[1][1] = operator[] (0)[0] / det;
	}

	return *result;
}

int TMatrix::resize(unsigned _width, unsigned _height)
{
	unsigned i;

	if (width != _width)
	{
		for (i = 0; i < width; i++)
			delete data[i];
		delete data;

		if (!(data = new PVector[width = _width]))
		{
			::MessageBox(NULL, "Нехватка памяти в resize", "TMatrix::Ошибка", MB_OK|MB_ICONSTOP);
			width = 0;
			return 0;
		}
		for (i = 0; i < width; i++)
			if (!(data[i] = new TVector(_height)) || !data[i]->data || !data[i]->length)
			{
				::MessageBox(NULL, "Нехватка памяти в resize", "TMatrix::Ошибка", MB_OK|MB_ICONSTOP);
				if (data[i])
					delete data[i];
				for (; i; )
					delete data[--i];
				delete data;
				data = 0;
				width = 0;
				return 0;
			}
	}
	else
	{
		if (height == _height)
			return 1;

		for (i = 0; i < width; i++)
			data[i]->resize(_height);
	}

	height = _height;

	return 1;
}

TVector &TMatrix::getmmax(void)
{
	TVector *result = new TVector(height);
	unsigned x, y;

	for (y = 0; y < height; y++)
		(*result)[y] = 0;
	for (x = 0; x < width; x++)
		for (y = 0; y < height; y++)
			if ((*result)[y] < fabs(operator[](x)[y]))
				(*result)[y] = fabs(operator[](x)[y]);

	return *result;
}

void TMatrix::write(FILE *outf)
{
	for (unsigned y = 0; y < height; y++)
	{
		operator() (y).write(outf);
		fprintf(outf, "\n");
	}
}
Соседние файлы в папке SOURCE