void Matrix<double>::Initialize( double (*initializer)(size_t, size_t, size_t, size_t) ) { for (size_t r = 0; r < GetRowLength(); ++r) { for (size_t c = 0; c < GetColumnLength(); ++c) { (*this)[r][c] = initializer(r, GetRowLength(), c, GetColumnLength()); } } }
Matrix<double> Matrix<double>::Transpose(void) const { Matrix<double> transposed(GetColumnLength(), GetRowLength()); for (size_t i = 0; i < GetRowLength(); ++i) { for (size_t j = 0; j < GetColumnLength(); ++j) { transposed[j][i] = (*this)[i][j]; } } return transposed; }
const Matrix<double> Matrix<double>::SubMatrix( size_t rowBegin, size_t rowEnd, size_t columnBegin, size_t columnEnd ) const { Matrix<double> m; if (rowEnd < rowBegin || columnEnd < columnBegin) { return m; } const size_t rowLength = rowEnd - rowBegin + 1; const size_t columnLength = columnEnd - columnBegin + 1; const size_t copyRowLength = std::min(rowLength, GetRowLength() - rowBegin); const size_t copyColumnLength = std::min(columnLength, GetColumnLength() - columnBegin); if (false == m.Resize(copyRowLength, copyColumnLength)) { return m; } for (size_t r = 0; r < copyRowLength; ++r) { const double* ptr = (*this)[r + rowBegin]; std::memcpy(m[r], ptr + columnBegin, copyColumnLength * sizeof(double)); } return m; }
Matrix<double> Matrix<double>::Multiply(const Matrix<double>& m) const { if ( GetColumnLength() != m.GetRowLength() ) { Matrix<double> null; return null; } Matrix<double> multiplied(GetRowLength(), m.GetColumnLength()); #if 0 for (size_t row = 0; row < multiplied.GetRowLength(); ++row) { for (size_t col = 0; col < multiplied.GetColumnLength(); ++col) { double v = 0; for (size_t k = 0; k < GetColumnLength(); ++k) { v += (*this)[row][k] * m[k][col]; } multiplied[row][col] = v; } } #else Matrix<double> transposed(m.T()); for (size_t row = 0; row < multiplied.GetRowLength(); ++row) { for (size_t col = 0; col < multiplied.GetColumnLength(); ++col) { multiplied[row][col] = (*this)[row].Dot(transposed[col]); } } #endif return multiplied; }
double Matrix<double>::Determinant(void) const { if ( GetColumnLength() != GetRowLength() ) { return 0; } int dimension = GetColumnLength(); double det = 0; const size_t _0 = 0; const size_t _1 = 1; const size_t _2 = 2; // Sarrus if ( 3 == dimension ) { const Matrix<double>&m = *this; det = m[_0][_0] * m[_1][_1] * m[_2][_2] + m[_0][_1] * m[_1][_2] * m[_2][_0] + m[_0][_2] * m[_1][_0] * m[_2][_1] - m[_0][_2] * m[_1][_1] * m[_2][_0] - m[_0][_1] * m[_1][_0] * m[_2][_2] - m[_0][_0] * m[_1][_2] * m[_2][_1]; } else if ( 2 == dimension ) { const Matrix<double>&m = *this; det = m[_0][_0] * m[_1][_1] - m[_0][_1] * m[_1][_0]; } else if ( 1 == dimension ) { const Matrix<double>&m = *this; det = m[_0][_0]; } else { for (size_t row = 0; row < GetRowLength(); ++row) { det += GetCofactor(row, 0) * (*this)[row][_0]; } } return det; }
Matrix<double>& Matrix<double>::operator=(const Matrix<double>& m) { Resize(m.GetRowLength(), m.GetColumnLength()); VectordBase* ptr = m_ObjectBase; for (size_t i = 0; i < GetRowLength(); ++i, ++ptr ) { *ptr = m[i]; } return *this; }
//------------------------------------------------------------------------- const char *FKCW_Base_CSVLoader::GetData(unsigned int rowIndex, unsigned int colIndex) { if (rowIndex >= (unsigned int)GetRowLength() || colIndex >= (unsigned int)GetColLength()) { return ""; } if (colIndex >= m_Datas[rowIndex].size()) { return ""; } return m_Datas[rowIndex][colIndex].c_str(); }
/** Key Press Event */ void TextArea::OnKeyPress(unsigned char Key, unsigned short /*Mod*/) { if (Flags & IE_GUI_TEXTAREA_EDITABLE) { if (Key >= 0x20) { Owner->Invalidate(); Changed = true; int len = GetRowLength(CurLine); //printf("len: %d Before: %s\n",len, lines[CurLine]); lines[CurLine] = (char *) realloc( lines[CurLine], len + 2 ); for (int i = len; i > CurPos; i--) { lines[CurLine][i] = lines[CurLine][i - 1]; } lines[CurLine][CurPos] = Key; lines[CurLine][len + 1] = 0; CurPos++; //printf("pos: %d After: %s\n",CurPos, lines[CurLine]); CalcRowCount(); RunEventHandler( TextAreaOnChange ); } return; } //Selectable=false for dialogs, rather unintuitive, but fact if ((Flags & IE_GUI_TEXTAREA_SELECTABLE) || ( Key < '1' ) || ( Key > '9' )) return; GameControl *gc = core->GetGameControl(); if (gc && (gc->GetDialogueFlags()&DF_IN_DIALOG) ) { Changed = true; seltext=minrow-1; if ((unsigned int) seltext>=lines.size()) { return; } for(int i=0;i<Key-'0';i++) { do { seltext++; if ((unsigned int) seltext>=lines.size()) { return; } } while (strnicmp( lines[seltext], "[s=", 3 ) != 0 ); } int idx=-1; sscanf( lines[seltext], "[s=%d,", &idx); if (idx==-1) { //this kills this object, don't use any more data! gc->EndDialog(); return; } gc->DialogChoose( idx ); } }
// Move current column position to end of line, if line is shorter, stay at // begining of line, if it is long enough move it to end and subtract // screen width / 2 from actual length int EList::MoveLineEnd() { int W, H, len; View->MView->Win->ConQuerySize(&W, &H); H--; len = GetRowLength(Row); if (len < W) { if (LeftCol != 0) { LeftCol = 0; NeedsUpdate = 1; } } else if (LeftCol != len - W / 2) { LeftCol = len - W / 2; NeedsUpdate = 1; } return ErOK; }
Matrix<double> Matrix<double>::GetCofactorMatrix(size_t row, size_t col) const { const size_t rowCount = GetRowLength(); const size_t colCount = GetColumnLength(); Matrix<double> cofactorMatrix(rowCount-1, colCount-1); for (size_t r = 0, ri = 0; ri < rowCount; ++ri) { if (ri == row) { continue; } for (size_t c = 0, ci = 0; ci < colCount; ++ci) { if (ci != col) { cofactorMatrix[r][c] = (*this)[ri][ci]; ++c; } } ++r; } return cofactorMatrix; }
/** Special Key Press */ void TextArea::OnSpecialKeyPress(unsigned char Key) { int len; int i; if (!(Flags&IE_GUI_TEXTAREA_EDITABLE)) { return; } Owner->Invalidate(); Changed = true; switch (Key) { case GEM_HOME: CurPos = 0; CurLine = 0; break; case GEM_UP: if (CurLine) { CurLine--; } break; case GEM_DOWN: if (CurLine<lines.size()) { CurLine++; } break; case GEM_END: CurLine=lines.size()-1; CurPos = GetRowLength((unsigned int) CurLine); break; case GEM_LEFT: if (CurPos > 0) { CurPos--; } else { if (CurLine) { CurLine--; CurPos = GetRowLength(CurLine); } } break; case GEM_RIGHT: len = GetRowLength(CurLine); if (CurPos < len) { CurPos++; } else { if(CurLine<lines.size()) { CurPos=0; CurLine++; } } break; case GEM_DELETE: len = GetRowLength(CurLine); //printf("len: %d Before: %s\n",len, lines[CurLine]); if (CurPos>=len) { //TODO: merge next line break; } lines[CurLine] = (char *) realloc( lines[CurLine], len ); for (i = CurPos; i < len; i++) { lines[CurLine][i] = lines[CurLine][i + 1]; } //printf("pos: %d After: %s\n",CurPos, lines[CurLine]); break; case GEM_BACKSP: len = GetRowLength(CurLine); if (CurPos != 0) { //printf("len: %d Before: %s\n",len, lines[CurLine]); if (len<1) { break; } lines[CurLine] = (char *) realloc( lines[CurLine], len ); for (i = CurPos; i < len; i++) { lines[CurLine][i - 1] = lines[CurLine][i]; } lines[CurLine][len - 1] = 0; CurPos--; //printf("pos: %d After: %s\n",CurPos, lines[CurLine]); } else { if (CurLine) { //TODO: merge lines int oldline = CurLine; CurLine--; int old = GetRowLength(CurLine); //printf("len: %d Before: %s\n",old, lines[CurLine]); //printf("len: %d Before: %s\n",len, lines[oldline]); lines[CurLine] = (char *) realloc (lines[CurLine], len+old); memcpy(lines[CurLine]+old, lines[oldline],len); free(lines[oldline]); lines[CurLine][old+len]=0; lines.erase(lines.begin()+oldline); lrows.erase(lrows.begin()+oldline); CurPos = old; //printf("pos: %d len: %d After: %s\n",CurPos, GetRowLength(CurLine), lines[CurLine]); } } break; case GEM_RETURN: //add an empty line after CurLine //printf("pos: %d Before: %s\n",CurPos, lines[CurLine]); lrows.insert(lrows.begin()+CurLine, 0); len = GetRowLength(CurLine); //copy the text after the cursor into the new line char *str = (char *) malloc(len-CurPos+2); memcpy(str, lines[CurLine]+CurPos, len-CurPos+1); str[len-CurPos+1] = 0; lines.insert(lines.begin()+CurLine+1, str); //truncate the current line lines[CurLine] = (char *) realloc (lines[CurLine], CurPos+1); lines[CurLine][CurPos]=0; //move cursor to next line beginning CurLine++; CurPos=0; //printf("len: %d After: %s\n",GetRowLength(CurLine-1), lines[CurLine-1]); //printf("len: %d After: %s\n",GetRowLength(CurLine), lines[CurLine]); break; } CalcRowCount(); RunEventHandler( TextAreaOnChange ); }
Matrix<double>& Matrix<double>::operator/=(double v) { MCON_ITERATION( i, GetRowLength(), (*this)[i] /= v); return *this; }
const Matrix<double> Matrix<double>::operator/(double v) const { Matrix<double> mat(*this); MCON_ITERATION( i, GetRowLength(), mat[i] /= v); return mat; }
Matrix<double> Matrix<double>::Inverse(void) const { if ( GetColumnLength() != GetRowLength() ) { return *this; } // Calculate Inversed-Matrix<double> by Cofactors. const size_t rowCount = GetRowLength(); const size_t colCount = GetColumnLength(); Matrix<double> inversed(rowCount, colCount); #if 0 double det = Determinant(); if ( 0 == det ) { return *this; } for (size_t row = 0; row < rowCount; ++row) { for (size_t col = 0; col < colCount; ++col) { int sign = ((row + col) & 1) ? -1 : 1; Matrix<double> m(GetCofactorMatrix(row, col)); inversed[col][row] = GetCofactor(row, col) / det; } } #else //-------------------------------- // Gauss-Jordan //-------------------------------- const double threshold = 1.0e-10; // TBD Matrix<double> m(rowCount, colCount * 2); if ( m.IsNull() ) { return m; } for (size_t row = 0; row < rowCount; ++row) { for (size_t col = 0; col < colCount; ++col) { m[row][col] = (*this)[row][col]; } } for (size_t row = 0; row < rowCount; ++row) { for (size_t col = colCount; col < colCount * 2; ++col) { if (row == (col - colCount)) { m[row][col] = 1.0; } else { m[row][col] = 0.0; } } } // 各行を正規化 for (size_t r = 0; r < m.GetRowLength(); ++r ) { m[r] /= m[r].GetMaximumAbsolute(); } for (size_t r = 0; r < m.GetRowLength(); ++r ) { // 注目している列の中で、最大値を持つ列を探す。 size_t index = r; double maximum = fabs(m[r][r]); // "k < m.GetRowLength() - 1" となっていたが、意図不明なので修正。 for (size_t k = index + 1; k < m.GetRowLength(); ++k ) { if ( fabs(m[k][r]) > maximum ) { index = k; maximum = fabs(m[k][r]); } } if ( maximum < threshold ) { // ここに到達することはないはず。 DEBUG_LOG(" ~ 0 at r=%d\n", static_cast<int>(r)); m.Resize(0, 0); // NULL を返す。 return m; } // 必要なら入れ替える if ( r != index ) { const Vectord tmp(m[r]); m[r] = m[index]; m[index] = tmp; } // 上で入れ替えたので 以降では index は不要、r を使用する。 // 注目している行の、注目している列の値を 1.0 にする m[r] /= m[r][r]; // /= maximum; // maximum では符号が考慮されない。 // 他の行から引く。 for (size_t k = 0; k < m.GetRowLength(); ++k ) { if ( k == r ) { continue; } const Vectord tmp(m[r]); m[k] -= (tmp * m[k][r]); } } for (size_t row = 0; row < rowCount; ++row) { for (size_t col = 0; col < colCount; ++col) { inversed[row][col] = m[row][col+colCount]; } } #endif return inversed; }