?? matrix.cpp
字號:
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
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 + -