⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matrix.cpp

📁 用于声音图像的FFC变换源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			else if (value > e_max)
				e_max = value ;
			}
		}
	min = e_min ;
	max = e_max ;
}

double CMatrix::SumColumn(int column) const
{
	ASSERT(column >= 0) ;					// bad column
	ASSERT(column < m_NumColumns) ;				// bad column
	double	sum = 0.0 ;

	for (int i = 0 ; i < m_NumRows ; ++i)
		sum += GetElement(column, i) ;
	return sum ;
}

double CMatrix::SumRow(int row) const
{
	ASSERT(row >= 0) ;						// bad row
	ASSERT(row < m_NumRows) ;					// bad row
	double	sum = 0.0 ;

	for (int i = 0 ; i < m_NumColumns ; ++i)
		sum += GetElement(i, row) ;
	return sum ;
}

double CMatrix::SumColumnSquared(int column) const
{
	double value = SumColumn(column) ;
	return (value * value) ;
}

double CMatrix::SumRowSquared(int row) const
{
	double value = SumRow(row) ;
	return (value * value) ;
}

// returns the minimum value in a row of the matrix
double CMatrix::GetRowMin(int row) const
{
	ASSERT(row >= 0) ;
	ASSERT(row < m_NumRows) ;
	double	value = GetElement(0, row) ;
	for (int i = 1 ; i < m_NumColumns ; ++i)
		{
		if (GetElement(i, row) < value)
			value = GetElement(i, row) ;
		}
	return value ;
}

// returns the maximum value in a row of the matrix
double CMatrix::GetRowMax(int row) const
{
	ASSERT(row >= 0) ;
	ASSERT(row < m_NumRows) ;
	double	value = GetElement(0, row) ;
	for (int i = 1 ; i < m_NumColumns ; ++i)
		{
		if (GetElement(i, row) > value)
			value = GetElement(i, row) ;
		}
	return value ;
}

// returns the minimum value in a column of the matrix
double CMatrix::GetColumnMin(int column) const
{
	ASSERT(column >= 0) ;
	ASSERT(column < m_NumColumns) ;
	double	value = GetElement(column, 0) ;
	for (int i = 1 ; i < m_NumRows ; ++i)
		{
		if (GetElement(column, i) < value)
			value = GetElement(column, i) ;
		}
	return value ;
}

// returns the maximum value in a column of the matrix
double CMatrix::GetColumnMax(int column) const
{
	ASSERT(column >= 0) ;
	ASSERT(column < m_NumColumns) ;
	double	value = GetElement(column, 0) ;
	for (int i = 1 ; i < m_NumRows ; ++i)
		{
		if (GetElement(column, i) > value)
			value = GetElement(column, i) ;
		}
	return value ;
}

// returns the matrix in a SafeArray object which can be passed through COM components and used in VB etc
VARIANT CMatrix::GetSafeArray() const
{
	VARIANT		var ;
	// Set up the VARIANT to hold the SAFEARRAY.
	SAFEARRAY*			psa = NULL ;
	SAFEARRAYBOUND		bounds[2] =	{
									{m_NumColumns, 0},
									{m_NumRows, 0}
									};

	VariantClear(&var) ;
	var.vt = VT_ARRAY | VT_R8 ;			// Double array.
	
	psa = SafeArrayCreate(VT_R8, 2, bounds) ;
	if (psa == NULL)					// failed to create the safe array
		{
		TRACE("Failed to create SAFEARRAY[][]\n") ;
		VariantClear(&var) ;
		return var ;
		}	
	double* dummy = NULL ;	
	SafeArrayAccessData(psa, (void**)(&dummy));	
	// Iterate through the array of doubles, placing each value into the dummy variable.
	for (int i = 0; i < m_NumColumns ; ++i)
		{
		for (int j = 0; j < m_NumRows ; ++j)
			dummy[i * m_NumRows + j] = GetElement(i, j) ;
		}
	SafeArrayUnaccessData(psa) ;
	// Set the array member of the VARIANT to be our newly filled SAFEARRAY.
	var.parray = psa;
	// note that to avoid a leak the variant must be cleared using "VariantClear"
	// to properly de-allocate the safe array just created
	return var ;
}

// copies the matrix to the clipboard as text such as:
// 
// 4.0,50.0,60.0
// 3.52,785.0,56.2
//
void CMatrix::CopyToClipboard() const
{
	// create the text to be copied to the clipboard
	CString	text ;

	for (int i = 0 ; i < m_NumRows ; ++i)
		{
		text += GetRowAsText(i) ;
		text += "\r\n" ;
		}
	// now place the text on the clipboard
	if (OpenClipboard(NULL))
		{
		HGLOBAL		handle ;
		char		*pntr ;

		handle = ::GlobalAlloc(GHND, text.GetLength() + 1) ;
		pntr = (char *)::GlobalLock(handle) ;
		strcpy(pntr, text) ;
		::GlobalUnlock(handle) ;
		EmptyClipboard() ;
		SetClipboardData(CF_TEXT, handle);
		CloseClipboard();
		}
}

void CMatrix::WriteAsCSVFile(const CString& filename) const
{
	// create the file to write to
	CFile	file ;
	
	try {
		if (file.Open(filename, CFile::modeWrite | CFile::modeCreate))
			{
			CString	text ;
			for (int i = 0 ; i < m_NumRows ; ++i)
				{
				text = GetRowAsText(i) ;
				file.Write(text, text.GetLength()) ;
				file.Write("\r\n", 2) ;			// eol
				}
			file.Close() ;
			}
		}
	catch (CFileException &e)
		{
		// we have has a problem, determine what it is
		switch (e.m_cause)
			{
			// errors that should not occur
			case CFileException::none :
			case CFileException::fileNotFound :
			case CFileException::removeCurrentDir :
			case CFileException::endOfFile :
				break ;
			// errors that require us to move the destination file
			case CFileException::badPath :
				AfxMessageBox("Bad file path") ;
				return ;
			case CFileException::directoryFull :
				AfxMessageBox("The destination directory is full") ;
				return ;
			case CFileException::diskFull :
				AfxMessageBox("The destination disk is full") ;
				return ;
			case CFileException::generic :
				AfxMessageBox("Generic (unknown error)") ;
				return ;
			case CFileException::tooManyOpenFiles :
				AfxMessageBox("Too many files are open") ;
				return ;
			case CFileException::accessDenied :
				AfxMessageBox("Access denied") ;
				return ;
			case CFileException::invalidFile :
				AfxMessageBox("Invalid file or name") ;
				return ;
			case CFileException::badSeek :
				AfxMessageBox("Bad seek on file") ;
				return ;
			case CFileException::hardIO :
				AfxMessageBox("Hardware IO error") ;
				return ;
			case CFileException::sharingViolation :
				AfxMessageBox("File sharing violation") ;
				return ;
			case CFileException::lockViolation :
				AfxMessageBox("File locking violation") ;
				return ;
			}
		}
}

// this function reads a file for "," separated values and creates a matrix object from it
CMatrix CMatrix::ReadFromCSVFile(const CString& filename)
{
	int		col_size = 0 ;
	int		row_size = 0 ;
	CFile	file ;

	try {
		if (file.Open(filename, CFile::modeRead))
			{
			CString	text = ReadLine(file) ;				// get a line from the file
			CString	token ;
			// count how many elements across their are
			int pos = 0 ;
			while (pos < text.GetLength())
				{
				pos = GetStringToken(text, token, pos, ',') ;
				col_size++ ;
				}
			// allocate an array to hold the data
			double	*pData = new double[col_size] ;
			CMatrix	m(col_size, 1) ;					// create a 1 row matrix which we will concatinate rows to

			while (text.GetLength() > 0)
				{
				int i = 0 ;
				pos = 0 ;
				while (pos < text.GetLength())
					{
					pos = GetStringToken(text, token, pos, ',') ;
					pData[i++] = atof(token) ;
					}
				ASSERT(i == col_size) ;
				text = ReadLine(file) ;
				if (row_size == 0)
					{
					// need to copy in the first row of data
					for (i = 0 ; i < col_size ; ++i)
						m.SetElement(i, 0, pData[i]) ;
					}
				else
					m.AddRow(pData) ;			// append to end of matrix
				row_size++ ;
				}
			delete []pData ;
			file.Close() ;
			return m ;
			}
		}
	catch (CFileException &e)
		{
		// we have has a problem, determine what it is
		switch (e.m_cause)
			{
			// errors that should not occur
			case CFileException::none :
			case CFileException::fileNotFound :
			case CFileException::removeCurrentDir :
			case CFileException::endOfFile :
				break ;
			// errors that require us to move the destination file
			case CFileException::badPath :
				AfxMessageBox("Bad file path") ;
				break ;
			case CFileException::directoryFull :
				AfxMessageBox("The destination directory is full") ;
				break ;
			case CFileException::diskFull :
				AfxMessageBox("The destination disk is full") ;
				break ;
			case CFileException::generic :
				AfxMessageBox("Generic (unknown error)") ;
				break ;
			case CFileException::tooManyOpenFiles :
				AfxMessageBox("Too many files are open") ;
				break ;
			case CFileException::accessDenied :
				AfxMessageBox("Access denied") ;
				break ;
			case CFileException::invalidFile :
				AfxMessageBox("Invalid file or name") ;
				break ;
			case CFileException::badSeek :
				AfxMessageBox("Bad seek on file") ;
				break ;
			case CFileException::hardIO :
				AfxMessageBox("Hardware IO error") ;
				break ;
			case CFileException::sharingViolation :
				AfxMessageBox("File sharing violation") ;
				break ;
			case CFileException::lockViolation :
				AfxMessageBox("File locking violation") ;
				break ;
			}
		}
	CMatrix problem ;
	return problem ;
}


// returns a row as , separated values
CString CMatrix::GetRowAsText(int row) const
{
	ASSERT(row >= 0) ;						// bad row
	ASSERT(row < m_NumRows) ;					// bad row
	CString	text ;
	CString	token ;

	for (int i = 0 ; i < m_NumColumns ; ++i)
		{
		if (i > 0)
			text += "," ;
		token.Format("%e", GetElement(i, row)) ;
		text += token ;
		}
	return text ;
}

// read a line of text from the current file
CString CMatrix::ReadLine(CFile& file)
{
	CString	line("") ;
	char	ch[3] ;
	DWORD	hBytesRead	= 0 ;

	while (true)
		{
		hBytesRead = file.Read(&ch[0], 2) ;
		if (hBytesRead == 2)
			file.Seek(-1L, CFile::current) ;		
		if (hBytesRead == 0)
			break ;					// end of file
		if (ch[0] == '\n')
			{
			if (ch[1] == '\r')
				file.Seek(1L, CFile::current) ;
			break ;
			}
		if (ch[0] == '\r')
			{
			ch[0] = '\n' ;
			if (ch[1] == '\n')
				file.Seek(1L, CFile::current) ;
			break ;
			}
		if (ch[0] != '\015')
			{
			// ignore LF characters
			ch[1] = '\0' ;
			line += ch ;
			}
		}
	return line ;
}

int CMatrix::GetStringToken(CString source, CString &destination, int start, char ch)
{
	ASSERT(start >= 0) ;

	// at the end of the source string ?
	if (start >= source.GetLength())
		{
		destination = "" ;					// no token available
		return source.GetLength() ;			// return @ end of string
		}
	
	// skip past any termination characters at the start position
	while (start < source.GetLength())
		{
		if (ch == source[start])
			start++ ;
		else
			break ;
		}
	// find the next occurance of the terminating character
	int pos = source.Find(ch, start) ;			// find termination character
	if (pos < 0)
		{
		// terminator not found, just return the remainder of the string
		destination = source.Right(source.GetLength() - start) ;
		return source.GetLength() ;
		}
	// found terminator, get sub string
	destination = source.Mid(start, pos - start) ;
	return pos ;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -