int main() { char** ppchReactants = NULL; int iReactantCounter = 0; SMatrix* qElementEquations = CreateMatrix( 0, 0 ); char** ppchElementNames = NULL; int iElementCounter = 0; SMatrix* qMatrixB = CreateMatrix( 0, 0 ); int iChangePoint; int iCount = 0; char* pchInput; pchInput = (char*)malloc( sizeof( char ) * 64 ); memset( pchInput, ' ', 64 ); printf( "Please enter the reactants one at a time.\nPlease use () to denote subscript.\nH(2)O for example. When finished enter '>'.\n\n" ); int iMult = 1; while( 1 ) { if( iMult == 1 ) { printf( "Enter reactant:\n" ); } else { printf( "Enter product:\n" ); } scanf( "%s", pchInput ); if( pchInput[0] == '>' ) { if( iMult == 1 ) { iChangePoint = iCount; iMult = -1; memset( pchInput, ' ', 64 ); continue; } else { break; } } ++iCount; int iLength = 0; while( pchInput[iLength] != ' ' ) { ++iLength; } pchInput[iLength-1] = '\0'; ++iReactantCounter; ppchReactants = (char**)realloc( ppchReactants, sizeof( char* ) * iReactantCounter ); ppchReactants[iReactantCounter-1] = (char*)malloc( sizeof( char ) * iLength ); memcpy( ppchReactants[iReactantCounter-1], pchInput, iLength ); int iPass = 0; for( int i = 0; i < (iLength-1); ++i ) { int iIncrement = 0; if( ( pchInput[i] >= 65 ) && ( pchInput[i] <= 90 ) ) { if( ( pchInput[i+1] >= 97 ) && ( pchInput[i+1] <= 122 ) ) { char* pchName = (char*)malloc( sizeof( char ) * 3 ); pchName[0] = pchInput[i]; pchName[1] = pchInput[i+1]; pchName[2] = '\0'; iIncrement += 1; int iAmount = 1; if( ( pchInput[i+2] == '(' ) && ( ( pchInput[i+3] >= 48 ) && ( pchInput[i+3] <= 57 ) ) ) { iIncrement += 1; char* chNumberBuffer = (char*)malloc( sizeof( char ) * 10 ); for( int j = 3; j <= 10; ++j ) { iIncrement += 1; if( pchInput[i+j] == ')' ) { break; } chNumberBuffer[j-3] = pchInput[i+j]; } iAmount = atoi( chNumberBuffer ); free( chNumberBuffer ); } int iPlace = -1; for( int j = 0; j < iElementCounter; ++j ) { if( !strcmp( pchName, ppchElementNames[j] ) ) { iPlace = j; } } if( iPlace == -1 ) { ++iElementCounter; ppchElementNames = (char**)realloc( ppchElementNames, sizeof( char* ) * iElementCounter ); ppchElementNames[iElementCounter-1] = (char*)malloc( sizeof( char ) * 3 ); memcpy( ppchElementNames[iElementCounter-1], pchName, 3 ); qElementEquations->m_iRows = iElementCounter; qElementEquations->m_ppdMatrix = (double**)realloc( qElementEquations->m_ppdMatrix, sizeof( double * ) * iElementCounter ); if( !iPass ) { for( int j = 0; j < iElementCounter; ++j ) { qElementEquations->m_iColumns = iReactantCounter; qElementEquations->m_ppdMatrix[j] = (double*)realloc( qElementEquations->m_ppdMatrix[j], sizeof( double ) * iReactantCounter ); qElementEquations->m_ppdMatrix[j][iReactantCounter-1] = 0; } } else { qElementEquations->m_ppdMatrix[iElementCounter-1] = (double*)malloc( sizeof( double ) * iReactantCounter ); } memset( qElementEquations->m_ppdMatrix[iElementCounter-1], 0, sizeof( double ) * ( iReactantCounter - 1 ) ); qElementEquations->m_ppdMatrix[iElementCounter-1][iReactantCounter-1] = ( iMult * iAmount ); } else { if( !iPass ) { for( int j = 0; j < iElementCounter; ++j ) { qElementEquations->m_iColumns = iReactantCounter; qElementEquations->m_ppdMatrix[j] = (double*)realloc( qElementEquations->m_ppdMatrix[j], sizeof( double ) * iReactantCounter ); qElementEquations->m_ppdMatrix[j][iReactantCounter-1] = 0; } } qElementEquations->m_ppdMatrix[iPlace][iReactantCounter-1] = ( iMult * iAmount ); } free( pchName ); } else { char* pchName = (char*)malloc( sizeof( char ) * 2 ); pchName[0] = pchInput[i]; pchName[1] = '\0'; int iAmount = 1; if( ( pchInput[i+1] == '(' ) && ( ( pchInput[i+2] >= 48 ) && ( pchInput[i+2] <= 57 ) ) ) { iIncrement += 1; char* chNumberBuffer = (char*)malloc( sizeof( char ) * 10 ); for( int j = 2; j <= 9; ++j ) { iIncrement += 1; if( pchInput[i+j] == ')' ) { break; } chNumberBuffer[j-2] = pchInput[i+j]; } iAmount = atoi( chNumberBuffer ); free( chNumberBuffer ); } int iPlace = -1; for( int j = 0; j < iElementCounter; ++j ) { if( !strcmp( pchName, ppchElementNames[j] ) ) { iPlace = j; } } if( iPlace == -1 ) { ++iElementCounter; ppchElementNames = (char**)realloc( ppchElementNames, sizeof( char* ) * iElementCounter ); ppchElementNames[iElementCounter-1] = (char*)malloc( sizeof( char ) * 2 ); memcpy( ppchElementNames[iElementCounter-1],pchName, 2 ); qElementEquations->m_iRows = iElementCounter; qElementEquations->m_ppdMatrix = (double**)realloc( qElementEquations->m_ppdMatrix, sizeof( double* ) * iElementCounter ); if( !iPass ) { for( int j = 0; j < iElementCounter; ++j ) { qElementEquations->m_iColumns = iReactantCounter; qElementEquations->m_ppdMatrix[j] = (double*)realloc( qElementEquations->m_ppdMatrix[j], sizeof( double ) * iReactantCounter ); qElementEquations->m_ppdMatrix[j][iReactantCounter-1] = 0; } } else { qElementEquations->m_iColumns = iReactantCounter; qElementEquations->m_ppdMatrix[iElementCounter-1] = (double*)malloc( sizeof( double ) * iReactantCounter ); } memset( qElementEquations->m_ppdMatrix[iElementCounter-1], 0, sizeof( double ) * ( iReactantCounter - 1 ) ); qElementEquations->m_ppdMatrix[iElementCounter-1][iReactantCounter-1] = ( iMult * iAmount ); } else { if( !iPass ) { for( int j = 0; j < iElementCounter; ++j ) { qElementEquations->m_iColumns = iReactantCounter; qElementEquations->m_ppdMatrix[j] = (double*)realloc( qElementEquations->m_ppdMatrix[j], sizeof( double ) * iReactantCounter ); qElementEquations->m_ppdMatrix[j][iReactantCounter-1] = 0; } } qElementEquations->m_ppdMatrix[iPlace][iReactantCounter-1] = ( iMult * iAmount ); } free( pchName ); } } if( pchInput[i] == '(' ) { int iCompoundLength = 1; int iParenCounter = 0; for( int j = 0; j < 64; ++j ) { ++iCompoundLength; if( pchInput[i+j] == '(' ) { ++iParenCounter; } if( pchInput[i+j] == ')' ) { --iParenCounter; } if( iParenCounter == 0 ) { break; } } iIncrement += ( iCompoundLength - 2 ); char* pchName = (char*)malloc( sizeof( char ) * iCompoundLength ); for( int j = 0; j < ( iCompoundLength ); ++j ) { pchName[j] = pchInput[i+j]; } pchName[iCompoundLength-1] = '\0'; int iAmount = 1; if( ( pchInput[i+iCompoundLength-1] == '(' ) && ( ( pchInput[i+iCompoundLength] >= 48 ) && ( pchInput[i+iCompoundLength] <= 57 ) ) ) { ++iIncrement; char* chNumberBuffer = (char*)malloc( sizeof( char ) * 10 ); for( int j = 0; j <= 9; ++j ) { ++iIncrement; if( pchInput[i+iCompoundLength+j] == ')' ) { break; } chNumberBuffer[j] = pchInput[i+iCompoundLength+j]; } iAmount = atoi( chNumberBuffer ); free( chNumberBuffer ); } int iPlace = -1; for( int j = 0; j < iElementCounter; ++j ) { if( !strcmp( pchName, ppchElementNames[j] ) ) { iPlace = j; } } if( iPlace == -1 ) { ++iElementCounter; ppchElementNames = (char**)realloc( ppchElementNames, sizeof( char* ) * iElementCounter ); ppchElementNames[iElementCounter-1] = (char*)malloc( sizeof( char ) * iCompoundLength ); memcpy( ppchElementNames[iElementCounter-1], pchName, iCompoundLength ); qElementEquations->m_iRows = iElementCounter; qElementEquations->m_ppdMatrix = (double**)realloc( qElementEquations->m_ppdMatrix, sizeof( double* ) * iElementCounter ); if( !iPass ) { for( int j = 0; j < iElementCounter; ++j ) { qElementEquations->m_iColumns = iReactantCounter; qElementEquations->m_ppdMatrix[j] = (double*)realloc( qElementEquations->m_ppdMatrix[j], sizeof( double ) * iReactantCounter ); qElementEquations->m_ppdMatrix[j][iReactantCounter-1] = 0; } } else { qElementEquations->m_iColumns = iReactantCounter; qElementEquations->m_ppdMatrix[iElementCounter-1] = (double*)malloc( sizeof( double ) * iReactantCounter ); } memset( qElementEquations->m_ppdMatrix[iElementCounter-1], 0, sizeof( double ) * ( iReactantCounter - 1 ) ); qElementEquations->m_ppdMatrix[iElementCounter-1][iReactantCounter-1] = ( iMult * iAmount ); } else { if( !iPass ) { for( int j = 0; j < iElementCounter; ++j ) { qElementEquations->m_iColumns = iReactantCounter; qElementEquations->m_ppdMatrix[j] = (double*)realloc( qElementEquations->m_ppdMatrix[j], sizeof( double ) * iReactantCounter ); qElementEquations->m_ppdMatrix[j][iReactantCounter-1] = 0; } } qElementEquations->m_ppdMatrix[iPlace][iReactantCounter-1] = ( iMult * iAmount ); } free( pchName ); } i+=iIncrement; ++iPass; } memset( pchInput, ' ', 64 ); } free( pchInput ); qMatrixB->m_iRows = iElementCounter; qMatrixB->m_iColumns = 1; qMatrixB->m_ppdMatrix = (double**)malloc( sizeof( double* ) * iElementCounter ); for( int i = 0; i < iElementCounter; ++i ) { qMatrixB->m_ppdMatrix[i] = (double*)malloc( sizeof( double ) * 1 ); qMatrixB->m_ppdMatrix[i][0] = fabs( qElementEquations->m_ppdMatrix[i][iReactantCounter-1] ); qElementEquations->m_ppdMatrix[i] = (double*)realloc( qElementEquations->m_ppdMatrix[i], sizeof( double ) * ( iReactantCounter - 1 ) ); } --iReactantCounter; --qElementEquations->m_iColumns; /* printf( "\nElement Equation Matrix:\n" ); for( int i = 0; i < iElementCounter; ++i ) { printf( "%s [", ppchElementNames[i] ); for( int j = 0; j < ( iReactantCounter + 1 ); ++j ) { if( j == iReactantCounter ) { printf( " = %6.2f ", qMatrixB->m_ppdMatrix[i][0] ); continue; } printf( " %6.2f ", qElementEquations->m_ppdMatrix[i][j] ); } printf( "]\n" ); } */ SMatrix* qMatrixA = SquareMatrix( qElementEquations ); /* printf( "\nMatrix A:\n" ); for( int i = 0; i < qMatrixA->m_iRows; ++i ) { for( int j = 0; j < qMatrixA->m_iRows; ++j ) { printf( "%6.2f", qMatrixA->m_ppdMatrix[i][j] ); } printf( "\n" ); } */ /* printf( "\nMatrix B:\n" ); for( int i = 0; i < iElementCounter; ++i ) { printf( "%6.2f\n", qMatrixB->m_ppdMatrix[i][0] ); } */ SMatrix* qMatrixAInverse = GetInverseMatrix( qMatrixA ); /* printf( "\nMatrix A Inverse:\n" ); for( int i = 0; i < qMatrixAInverse->m_iRows; ++i ) { for( int j = 0; j < qMatrixAInverse->m_iRows; ++j ) { printf( "%6.2f", qMatrixAInverse->m_ppdMatrix[i][j] ); } printf( "\n" ); } */ double dDet = (double)DeterminantOfMatrix( qMatrixA ); SMatrix* qFirstMatrix = MultiplyMatrixes( qMatrixAInverse, qMatrixB ); /* printf( "\nMatrix A^-1 * Matrix B:\n" ); for( int i = 0; i < qFirstMatrix->m_iRows; ++i ) { printf( "%6.2f\n", qFirstMatrix->m_ppdMatrix[i][0] ); } */ /* printf( "\nDeterminant of Matrix A: %.0f\n", fDet ); */ MultiplyByConstant( qFirstMatrix, dDet ); int iGCDArray[100]; for( int i = 0; i < ( iReactantCounter + 1 ); ++i ) { if( i != ( iReactantCounter ) ) { iGCDArray[i] = qFirstMatrix->m_ppdMatrix[i][0]; } else { iGCDArray[i] = dDet; } } int iGCD = GreatestCommonDenominatorArray( iGCDArray, ( iReactantCounter + 1 ) ); /* printf( "\n( Matrix A^-1 * Matrix B ) * det( Matrix A ):\n" ); for( int i = 0; i < iSquare; ++i ) { printf( "%6.2f\n", ppdFirstMatrix[i][0] ); } */ printf( "\nYour final solution is:\n" ); int iFirst = 1; for( int i = 0; i < iChangePoint; ++i ) { if( iFirst ) { printf( "%.0f", fabs( qFirstMatrix->m_ppdMatrix[i][0] / iGCD ) ); printf( "%s", ppchReactants[i] ); iFirst = 0; } else { printf( " + " ); printf( "%.0f", fabs( qFirstMatrix->m_ppdMatrix[i][0] / iGCD ) ); printf( "%s", ppchReactants[i] ); } } printf( " -> " ); iFirst = 1; for( int i = iChangePoint; i < (iReactantCounter+1); ++i ) { if( i != ( iReactantCounter ) ) { if( iFirst ) { printf( "%.0f", fabs( qFirstMatrix->m_ppdMatrix[i][0] / iGCD ) ); printf( "%s", ppchReactants[i] ); iFirst = 0; } else { printf( " + " ); printf( "%.0f", fabs( qFirstMatrix->m_ppdMatrix[i][0] / iGCD ) ); printf( "%s", ppchReactants[i] ); } } else { if( iFirst ) { printf( "%.0f", fabs( dDet / iGCD ) ); printf( "%s", ppchReactants[i] ); } else { printf( " + " ); printf( "%.0f", fabs( dDet / iGCD ) ); printf( "%s", ppchReactants[i] ); } } } FreeMatrix( qElementEquations ); FreeMatrix( qMatrixB ); FreeMatrix( qMatrixA ); FreeMatrix( qMatrixAInverse ); FreeMatrix( qFirstMatrix ); // ppchElementNames for( int i = 0; i < iElementCounter; ++i ) { free( ppchElementNames[i] ); } free( ppchElementNames ); //Free ppchReactants for( int i = 0; i < ( iReactantCounter + 1 ); ++i ) { free( ppchReactants[i] ); } free( ppchReactants ); return 0; }
Vector2f Drawable::TransformToLocal(const Vector2f& point) const { return GetInverseMatrix().Transform(point); }