public SolucaoFluxoPotenciaMatrizZ(Sparse2DMatrix <int, int, Complex> Y_mat, Barra Bar, Linha Lin) { Barra = Bar; Linha = Lin; Y_matriz = Y_mat; Calcula_Z_matriz(); }
public SolucaoFluxoNewtonRaphsonDesacoplado(Sparse2DMatrix <int, int, double> G_mat, Sparse2DMatrix <int, int, double> B_mat, Barra Bar, Linha Lin) { G_matriz = G_mat; B_matriz = B_mat; Barra = Bar; Linha = Lin; }
public void PreencherTabelaComplexa(DataGridView grade, Sparse2DMatrix <int, int, Complex> Matriz) { DataTable tabela = new DataTable(); for (int i = 1; i <= Barra.NBarra.Count; i++) { tabela.Columns.Add("Barra " + Convert.ToString(i), typeof(Complex)); } DataRow row = tabela.NewRow(); for (int k = 1; k <= Barra.NBarra.Count; k++) { row[k - 1] = Matriz[iteracao - 1, k]; } tabela.Rows.Add(row); grade.DataSource = tabela; }
public void PreencherTabela(DataGridView grade, Sparse2DMatrix <int, int, double> Matriz) { DataTable tabela = new DataTable(); for (int i = 1; i <= Barra.NBarra.Count; i++) { tabela.Columns.Add(Convert.ToString(i), typeof(double)); } for (int i = 1; i <= Barra.NBarra.Count; i++) { DataRow row = tabela.NewRow(); for (int k = 1; k <= Barra.NBarra.Count; k++) { row[k - 1] = Matriz[i, k]; } tabela.Rows.Add(row); } grade.DataSource = tabela; }
public RegionFile(string filename) { columns = RegionFile.Read(filename).columns; }
private void Solve() { mainToolStripStatusLabel.Text = Properties.Resources.IDS_SOLVING_EQUATIONS; Sparse2DMatrix <int, int, double> aMatrix = new Sparse2DMatrix <int, int, double>(); SparseArray <int, double> bVector = new SparseArray <int, double>(); SparseArray <string, int> variableNameIndexMap = new SparseArray <string, int>(); int numberOfEquations = 0; LinearEquationParser parser = new LinearEquationParser(); LinearEquationParserStatus parserStatus = LinearEquationParserStatus.Success; foreach (string inputLine in equationsRichTextBox.Lines) { parserStatus = parser.Parse(inputLine, aMatrix, bVector, variableNameIndexMap, ref numberOfEquations); if (parserStatus != LinearEquationParserStatus.Success) { break; } } // Assume success. string mainStatusBarText = Properties.Resources.IDS_EQUATIONS_SOLVED; // Did an error occur? if (parserStatus == LinearEquationParserStatus.Success) { // Are there the same number of equations as variables? if (numberOfEquations == variableNameIndexMap.Count) { // Create a solution vector. SparseArray <int, double> xVector = new SparseArray <int, double>(); // Solve the simultaneous equations. LinearEquationSolverStatus solverStatus = LinearEquationSolver.Solve(numberOfEquations, aMatrix, bVector, xVector); if (solverStatus == LinearEquationSolverStatus.Success) { string solutionString = ""; foreach (KeyValuePair <string, int> pair in variableNameIndexMap) { solutionString += string.Format("{0} = {1}", pair.Key, xVector[pair.Value]); solutionString += "\n"; } equationsRichTextBox.Text += "\n" + solutionString; } else if (solverStatus == LinearEquationSolverStatus.IllConditioned) { mainStatusBarText = Properties.Resources.IDS_ILL_CONDITIONED_SYSTEM_OF_EQUATIONS; } else if (solverStatus == LinearEquationSolverStatus.Singular) { mainStatusBarText = Properties.Resources.IDS_SINGULAR_SYSTEM_OF_EQUATIONS; } } else if (numberOfEquations < variableNameIndexMap.Count) { mainStatusBarText = string.Format(Properties.Resources.IDS_TOO_FEW_EQUATIONS, numberOfEquations, variableNameIndexMap.Count); } else if (numberOfEquations > variableNameIndexMap.Count) { mainStatusBarText = string.Format(Properties.Resources.IDS_TOO_MANY_EQUATIONS, numberOfEquations, variableNameIndexMap.Count); } } else { // An error occurred. Report the error in the status bar. mainStatusBarText = LinearEquationParserStatusInterpreter.GetStatusString(parserStatus); } mainToolStripStatusLabel.Text = mainStatusBarText; }
public string SolveEquation(string equation) { Sparse2DMatrix <int, int, double> aMatrix = new Sparse2DMatrix <int, int, double>(); SparseArray <int, double> bVector = new SparseArray <int, double>(); SparseArray <string, int> variableNameIndexMap = new SparseArray <string, int>(); int numberOfEquations = 0; LinearEquationParser parser = new LinearEquationParser(); LinearEquationParserStatus parserStatus = LinearEquationParserStatus.Success; string[] lines = equation.Split(new[] { "\r\n", "\r", "\n", "\\n", "," }, StringSplitOptions.None); foreach (string inputLine in lines) { parserStatus = parser.Parse(inputLine, aMatrix, bVector, variableNameIndexMap, ref numberOfEquations); if (parserStatus != LinearEquationParserStatus.Success) { break; } } // Assume success. string mainStatusBarText = "Equations solved"; // Did an error occur? if (parserStatus == LinearEquationParserStatus.Success) { // Are there the same number of equations as variables? if (numberOfEquations == variableNameIndexMap.Count) { // Create a solution vector. SparseArray <int, double> xVector = new SparseArray <int, double>(); // Solve the simultaneous equations. LinearEquationSolverStatus solverStatus = LinearEquationSolver.Solve(numberOfEquations, aMatrix, bVector, xVector); if (solverStatus == LinearEquationSolverStatus.Success) { string solutionString = ""; foreach (KeyValuePair <string, int> pair in variableNameIndexMap) { solutionString += string.Format("{0} = {1}" + " ", pair.Key, xVector[pair.Value]); } return(solutionString); } else if (solverStatus == LinearEquationSolverStatus.IllConditioned) { mainStatusBarText = "Error - the system of equations is ill conditioned."; } else if (solverStatus == LinearEquationSolverStatus.Singular) { mainStatusBarText = "Error - the system of equations is singular."; } } else if (numberOfEquations < variableNameIndexMap.Count) { mainStatusBarText = string.Format("Only {0} equations is too few equations for {1} variables", numberOfEquations, variableNameIndexMap.Count); } else if (numberOfEquations > variableNameIndexMap.Count) { mainStatusBarText = string.Format("{0} equations is too many equations for only {1} variables", numberOfEquations, variableNameIndexMap.Count); } } else { // An error occurred. Report the error in the status bar. mainStatusBarText = LinearEquationParserStatusInterpreter.GetStatusString(parserStatus); } return(mainStatusBarText); }
/// <summary> /// This function solves simultaneous equations in matrix form. /// The equations are represented by the matrix equation: /// /// aMatrix xVector = bVector /// /// The algorithm is from the book: /// "Mathematical Methods For Digital Computers" Volume 2 /// Edited by Anthony Ralston and Herbert S. Wilf, 1967, /// John Wiley and Sons, pages 65-93. /// "The solution of ill-conditioned linear equations" /// by J. H. Wilkinson. /// </summary> /// <param name="numberOfEquations">The number of equations</param> /// <param name="aMatrix">A square matrix</param> /// <param name="bVector">A vector that contains the right hand side of the matrix equations shown below.</param> /// <param name="xVector">A vector to contain the solution of the matrix equations.</param> /// <returns> /// This function returns an enumerated value of type Status_T /// that is the value LinearEquationSolverStatus.Singular if the /// coefficient matrix is singular to working accuracy. A value of /// LinearEquationSolverStatus.IllConditioned is returned if the /// coefficient matrix is singular to working accuracy, i.e. the /// floating point arithmetic does not have enough precision to /// guarantee convergence to an accurate solution. /// The value LinearEquationSolverStatus.Success is returned /// if the solution vector was calculated successfully. /// </returns> public static LinearEquationSolverStatus Solve(int numberOfEquations, Sparse2DMatrix <int, int, double> aMatrix, SparseArray <int, double> bVector, SparseArray <int, double> xVector) { //---------------------------------------------------------- // Matrix a_matrix is copied into working matrix aMatrixCopy. //---------------------------------------------------------- Sparse2DMatrix <int, int, double> aMatrixCopy = new Sparse2DMatrix <int, int, double>(aMatrix); //---------------------------------------------------------- // The maximum value rowMaximumVector[i], i = 0 to n - 1 // is stored //---------------------------------------------------------- SparseArray <int, double> rowMaximumVector = new SparseArray <int, double>(); int i = 0; for (i = 0; i < numberOfEquations; i++) { double temp = 0.0; for (int j = 0; j < numberOfEquations; j++) { double test = Math.Abs(aMatrix[i, j]); if (test > temp) { temp = test; } } rowMaximumVector[i] = temp; //---------------------------------------------------------- // Test for singular matrix. //---------------------------------------------------------- if (temp == 0.0) { return(LinearEquationSolverStatus.Singular); } } //---------------------------------------------------------- // The r'th column of "l", the r'th pivotal position r', and // the r'th row of "u" are determined. //---------------------------------------------------------- SparseArray <int, int> pivotRowArray = new SparseArray <int, int>(); for (int r = 0; r < numberOfEquations; r++) { double maximumValue = 0.0; int rowMaximumValueIndex = r; //---------------------------------------------------------- // The l[i][r], i = r to n - 1 are determined. // l[i][r] is a lower triangular matrix. It is calculated // using the variable temp and copied into matrix // "aMatrixCopy". The variable "maximumValue" contains // the largest Math.Abs(l[i][r] / pivotRowArray[i]) and // rowMaximumValueIndex stores the "i" which corresponds // to the value in variable maximumValue. //---------------------------------------------------------- double temp; for (i = r; i < numberOfEquations; i++) { temp = aMatrixCopy[i, r]; for (int j = 0; j < r; j++) { temp = temp - aMatrixCopy[i, j] * aMatrixCopy[j, r]; } aMatrixCopy[i, r] = temp; double test = Math.Abs(temp / rowMaximumVector[i]); if (test > maximumValue) { maximumValue = test; rowMaximumValueIndex = i; } } //---------------------------------------------------------- // Test for matrix which is singular to working precision. //---------------------------------------------------------- if (maximumValue == 0.0) { return(LinearEquationSolverStatus.IllConditioned); } //---------------------------------------------------------- // "rowMaximumValueIndex" = r' and "pivotRowArray[r]" // is the pivotal row. //---------------------------------------------------------- rowMaximumVector[rowMaximumValueIndex] = rowMaximumVector[r]; pivotRowArray[r] = rowMaximumValueIndex; //---------------------------------------------------------- // Rows "r" and "pivotRowArray[r]" are exchanged. //---------------------------------------------------------- for (i = 0; i < numberOfEquations; i++) { temp = aMatrixCopy[r, i]; aMatrixCopy[r, i] = aMatrixCopy[rowMaximumValueIndex, i]; aMatrixCopy[rowMaximumValueIndex, i] = temp; } //---------------------------------------------------------- // The u[r][i], i = r + 1 to n - 1 are determined. // "u[r][i]" is an upper triangular matrix. It is copied // into aMatrixCopy. //---------------------------------------------------------- for (i = r + 1; i < numberOfEquations; i++) { temp = aMatrixCopy[r, i]; for (int j = 0; j < r; j++) { temp = temp - aMatrixCopy[r, j] * aMatrixCopy[j, i]; } aMatrixCopy[r, i] = temp / aMatrixCopy[r, r]; } } //---------------------------------------------------------- // The first solution vector is set equal to the null vector // and the first residuals are set equal to the equation // constant vector. //---------------------------------------------------------- SparseArray <int, double> residualVector = new SparseArray <int, double>(); for (i = 0; i < numberOfEquations; i++) { xVector[i] = 0.0; residualVector[i] = bVector[i]; } //---------------------------------------------------------- // The iteration counter is initialized. //---------------------------------------------------------- int iteration = 0; bool notConvergedFlag = true; do { //---------------------------------------------------------- // The forward substitution is performed and the solution // of l y = p r is calculated where p r is the current // residual after interchanges. //---------------------------------------------------------- for (i = 0; i < numberOfEquations; i++) { int pivotRowIndex = pivotRowArray[i]; double temp = residualVector[pivotRowIndex]; residualVector[pivotRowIndex] = residualVector[i]; for (int j = 0; j < i; j++) { temp = temp - aMatrixCopy[i, j] * residualVector[j]; } residualVector[i] = temp / aMatrixCopy[i, i]; } //---------------------------------------------------------- // The back substitution is performed and the solution of // u e = y is calculated. The current correction is stored // in variable residualVector. //---------------------------------------------------------- for (i = numberOfEquations - 1; i >= 0; i--) { double temp = residualVector[i]; for (int j = i + 1; j < numberOfEquations; j++) { temp = temp - aMatrixCopy[i, j] * residualVector[j]; } residualVector[i] = temp; } //---------------------------------------------------------- // The norm of the error in the residuals and the norm of // the present solution vector are calculated. //---------------------------------------------------------- double normOfX = 0.0; double normOfError = 0.0; for (i = 0; i < numberOfEquations; i++) { double test = Math.Abs(xVector[i]); if (test > normOfX) { normOfX = test; } test = Math.Abs(residualVector[i]); if (test > normOfError) { normOfError = test; } } //---------------------------------------------------------- // If iteration is zero then skip this section because // no correction exists on the first iteration. //---------------------------------------------------------- if (iteration != 0) { //------------------------------------------------------ // Test for matrix which is singular to working // precision. //------------------------------------------------------ if ((iteration == 1) && (normOfError / normOfX > 0.5)) { return(LinearEquationSolverStatus.IllConditioned); } //------------------------------------------------------ // Check to see if "normOfError" / "normOfX" is greater // than 2 ^ (1 - t), where "t" is the number of bits // in the mantissa of a double precision number. If // this is not true then the last correction is almost // negligible and "notConvergedFlag" is set to false. //------------------------------------------------------ notConvergedFlag = normOfError / normOfX >= s_smallFloatingPointValue; } //---------------------------------------------------------- // The corrections (residuals) are added to the // solution vector. //---------------------------------------------------------- for (i = 0; i < numberOfEquations; i++) { xVector[i] = xVector[i] + residualVector[i]; } //---------------------------------------------------------- // The new residuals corresponding to the solution vector // are calculated. //---------------------------------------------------------- for (i = 0; i < numberOfEquations; i++) { double temp = bVector[i]; for (int j = 0; j < numberOfEquations; j++) { temp = temp - aMatrix[i, j] * xVector[j]; } residualVector[i] = temp; } //---------------------------------------------------------- // The iteration counter is incremented and the flag // "notConvergedFlag" is tested. If notConvergedFlag is false // then the solution vector has converged to sufficient // accuracy. //---------------------------------------------------------- iteration++; }while (notConvergedFlag); return(LinearEquationSolverStatus.Success); }
public static LinearEquationSolverStatus Solve(int numberOfEquations, Sparse2DMatrix <int, int, double> aMatrix, SparseArray <int, double> bVector, SparseArray <int, double> xVector) { //---------------------------------------------------------- // Matrix a_matrix is copied into working matrix aMatrixCopy. //---------------------------------------------------------- Sparse2DMatrix <int, int, double> aMatrixCopy = new Sparse2DMatrix <int, int, double>(aMatrix); //---------------------------------------------------------- // The maximum value rowMaximumVector[i], i = 0 to n - 1 // is stored //---------------------------------------------------------- SparseArray <int, double> rowMaximumVector = new SparseArray <int, double>(); int i = 0; for (i = 0; i < numberOfEquations; i++) { double temp = 0.0; for (int j = 0; j < numberOfEquations; j++) { double test = Math.Abs(aMatrix[i, j]); if (test > temp) { temp = test; } } rowMaximumVector[i] = temp; //---------------------------------------------------------- // Test for singular matrix. //---------------------------------------------------------- if (temp == 0.0) { return(LinearEquationSolverStatus.Singular); } } //---------------------------------------------------------- // The r'th column of "l", the r'th pivotal position r', and // the r'th row of "u" are determined. //---------------------------------------------------------- SparseArray <int, int> pivotRowArray = new SparseArray <int, int>(); for (int r = 0; r < numberOfEquations; r++) { double maximumValue = 0.0; int rowMaximumValueIndex = r; double temp; for (i = r; i < numberOfEquations; i++) { temp = aMatrixCopy[i, r]; for (int j = 0; j < r; j++) { temp = temp - aMatrixCopy[i, j] * aMatrixCopy[j, r]; } aMatrixCopy[i, r] = temp; double test = Math.Abs(temp / rowMaximumVector[i]); if (test > maximumValue) { maximumValue = test; rowMaximumValueIndex = i; } } //---------------------------------------------------------- // Test for matrix which is singular to working precision. //---------------------------------------------------------- if (maximumValue == 0.0) { return(LinearEquationSolverStatus.IllConditioned); } //---------------------------------------------------------- // "rowMaximumValueIndex" = r' and "pivotRowArray[r]" // is the pivotal row. //---------------------------------------------------------- rowMaximumVector[rowMaximumValueIndex] = rowMaximumVector[r]; pivotRowArray[r] = rowMaximumValueIndex; //---------------------------------------------------------- // Rows "r" and "pivotRowArray[r]" are exchanged. //---------------------------------------------------------- for (i = 0; i < numberOfEquations; i++) { temp = aMatrixCopy[r, i]; aMatrixCopy[r, i] = aMatrixCopy[rowMaximumValueIndex, i]; aMatrixCopy[rowMaximumValueIndex, i] = temp; } for (i = r + 1; i < numberOfEquations; i++) { temp = aMatrixCopy[r, i]; for (int j = 0; j < r; j++) { temp = temp - aMatrixCopy[r, j] * aMatrixCopy[j, i]; } aMatrixCopy[r, i] = temp / aMatrixCopy[r, r]; } } SparseArray <int, double> residualVector = new SparseArray <int, double>(); for (i = 0; i < numberOfEquations; i++) { xVector[i] = 0.0; residualVector[i] = bVector[i]; } //---------------------------------------------------------- // The iteration counter is initialized. //---------------------------------------------------------- int iteration = 0; bool notConvergedFlag = true; do { //---------------------------------------------------------- // The forward substitution is performed and the solution // of l y = p r is calculated where p r is the current // residual after interchanges. //---------------------------------------------------------- for (i = 0; i < numberOfEquations; i++) { int pivotRowIndex = pivotRowArray[i]; double temp = residualVector[pivotRowIndex]; residualVector[pivotRowIndex] = residualVector[i]; for (int j = 0; j < i; j++) { temp = temp - aMatrixCopy[i, j] * residualVector[j]; } residualVector[i] = temp / aMatrixCopy[i, i]; } //---------------------------------------------------------- // The back substitution is performed and the solution of // u e = y is calculated. The current correction is stored // in variable residualVector. //---------------------------------------------------------- for (i = numberOfEquations - 1; i >= 0; i--) { double temp = residualVector[i]; for (int j = i + 1; j < numberOfEquations; j++) { temp = temp - aMatrixCopy[i, j] * residualVector[j]; } residualVector[i] = temp; } //---------------------------------------------------------- // The norm of the error in the residuals and the norm of // the present solution vector are calculated. //---------------------------------------------------------- double normOfX = 0.0; double normOfError = 0.0; for (i = 0; i < numberOfEquations; i++) { double test = Math.Abs(xVector[i]); if (test > normOfX) { normOfX = test; } test = Math.Abs(residualVector[i]); if (test > normOfError) { normOfError = test; } } //---------------------------------------------------------- // If iteration is zero then skip this section because // no correction exists on the first iteration. //---------------------------------------------------------- if (iteration != 0) { //------------------------------------------------------ // Test for matrix which is singular to working // precision. //------------------------------------------------------ if ((iteration == 1) && (normOfError / normOfX > 0.5)) { return(LinearEquationSolverStatus.IllConditioned); } notConvergedFlag = normOfError / normOfX >= s_smallFloatingPointValue; #if DEBUGCODE double normRatioForDebug = normOfError / normOfX; #endif } //---------------------------------------------------------- // The corrections (residuals) are added to the // solution vector. //---------------------------------------------------------- for (i = 0; i < numberOfEquations; i++) { xVector[i] = xVector[i] + residualVector[i]; } //---------------------------------------------------------- // The new residuals corresponding to the solution vector // are calculated. //---------------------------------------------------------- for (i = 0; i < numberOfEquations; i++) { double temp = bVector[i]; for (int j = 0; j < numberOfEquations; j++) { temp = temp - aMatrix[i, j] * xVector[j]; } residualVector[i] = temp; } iteration++; }while (notConvergedFlag); return(LinearEquationSolverStatus.Success); }
public SolucaoFluxoPotenciaGaussSiedel(Sparse2DMatrix <int, int, Complex> Y_mat, Barra Bar, Linha Lin) { Barra = Bar; Linha = Lin; Y_matriz = Y_mat; }
public void Run(TimeMapOptions options) { // Set up the world, which will be used to find the files in the world. var world = options.GetWorld(); // To properly scale the histogram, all chunks must be scanned. A 2D sparse matrix is used // to store the inhabited times for each chunk. While that is being populated, the histogram // is also created. var matrix = new Sparse2DMatrix <int, int, long>(); var colorMap = new ColorMap(); foreach (var regionPath in world.ListRegionPaths()) { var region = new Region(regionPath); // TODO - region should expose a Coordinate2D, not separate X and Z values var regionPt = new Coordinate2D(region.X, region.Z, CoordinateType2D.Region); Console.WriteLine("Region {0}, X={1}, Z={2}:", regionPath, region.X, region.Z); var found = 0; for (var x = 0; x < 32; x++) { for (var z = 0; z < 32; z++) { var pt = new Coordinate2D(x, z, CoordinateType2D.ChunkWithinRegion).ToChunk(regionPt); if (region.HasChunk(pt)) { found += 1; var chunk = region.GetChunk(pt); var time = chunk.InhabitedTime; matrix[pt.X, pt.Z] = time; colorMap.AddSample(time); } } } Console.WriteLine(" {0} chunks", found); } // Set up the transformation from chunk coords to pixel coords var dx = matrix.MaxX - matrix.MinX; var dy = matrix.MaxY - matrix.MinY; var transform = new Transform2D(); transform.InputRange(matrix.MinX, matrix.MaxX, matrix.MinY, matrix.MaxY); transform.OutputRange(0, dx - 1, 0, dy - 1); // Use the data to create the image using (var image = new Image <Rgba32>(dx * options.ChunkSize, dy * options.ChunkSize)) { for (var x = matrix.MinX; x < matrix.MaxX; x++) { for (var y = matrix.MinY; y < matrix.MaxY; y++) { var val = matrix[x, y]; var black = new Rgba32(0, 0, 0, 255); Rgba32 color; if (val == 0) { color = black; } else { color = colorMap.GetColor(val); } var px = options.ChunkSize * (int)transform.TransformX(x); var py = options.ChunkSize * (int)transform.TransformY(y); for (var xx = 0; xx < options.ChunkSize; xx++) { for (var yy = 0; yy < options.ChunkSize; yy++) { image[px + xx, py + yy] = color; } } } } image.SaveAsPng(options.OutputPath); Console.WriteLine("Wrote image to {0}.", options.OutputPath); } }
/// <summary> /// This method gets a term in the simultaneous equation. The term /// can be a number, a variable, or a number and a variable. A term /// cannot be split between lines input to this method. /// </summary> /// <param name="inputLine">The input line to be parsed</param> /// <param name="positionIndex">The current parse position in the input string.</param> /// <param name="aMatrix">The A matrix for the simultaneous equations. /// This is updated as each line of input is parsed. /// </param> /// <param name="bVector">The B vector for the simultaneous equations. /// This is updated as each line of input is parsed.</param> /// <param name="variableNameIndexMap">A map that stores the integer /// index for a variable using the variable name as a key.</param> /// <returns>This method returns the value 'true' if and only if a term is found. /// </returns> private bool GetTerm(string inputLine, ref int positionIndex, Sparse2DMatrix <int, int, double> aMatrix, SparseArray <int, double> bVector, SparseArray <string, int> variableNameIndexMap) { //------------------------------------------------------------------ // A term is one of the following three patterns. // // <Space> <Sign> Number <Space> // <Space> <Sign> Variable <Space> // <Space> <Sign> Number Variable <Space> // // Check for a plus or a minus sign at the start of a term. //------------------------------------------------------------------ bool numberIsNegativeFlag = false; GetSign(inputLine, ref positionIndex, ref numberIsNegativeFlag); //------------------------------------------------------------------ // Skip whitespace characters //------------------------------------------------------------------ SkipSpaces(inputLine, ref positionIndex); //------------------------------------------------------------------ // Check to see if this is a number or a variable. //------------------------------------------------------------------ string numberString = ""; bool haveNumberFlag = GetNumber(inputLine, ref positionIndex, ref numberString); //------------------------------------------------------------------ // If an error then abort. //------------------------------------------------------------------ if (LastStatusValue != LinearEquationParserStatus.Success) { return(false); } //------------------------------------------------------------------ // If there was a number encountered then test to see if the // number has an exponent. //------------------------------------------------------------------ if (haveNumberFlag) { if (positionIndex < inputLine.Length) { //---------------------------------------------------------- // Does the number have an exponent? //---------------------------------------------------------- if (inputLine[positionIndex] == '^') { positionIndex++; //------------------------------------------------------ // Does the exponent have a sign. //------------------------------------------------------ bool negativeExponentFlag = false; GetSign(inputLine, ref positionIndex, ref negativeExponentFlag); //------------------------------------------------------ // Get the exponent digits. //------------------------------------------------------ string exponentString = ""; if (GetNumber(inputLine, ref positionIndex, ref exponentString)) { //-------------------------------------------------- // Is the exponent a valid exponent. //-------------------------------------------------- int exponentLength = exponentString.Length; if (exponentLength <= 2) { bool exponent_error_flag = false; for (int i = 0; i < exponentLength; ++i) { if (!Char.IsDigit(exponentString[i])) { exponent_error_flag = true; } } if (!exponent_error_flag) { numberString += 'E'; if (negativeExponentFlag) { numberString += '-'; } numberString += exponentString; } else { SetLastStatusValue(LinearEquationParserStatus.ErrorIllegalExponent, positionIndex); return(false); } } else { SetLastStatusValue(LinearEquationParserStatus.ErrorIllegalExponent, positionIndex); return(false); } } else { SetLastStatusValue(LinearEquationParserStatus.ErrorMissingExponent, positionIndex); return(false); } } } } //------------------------------------------------------------------ // Skip whitespace characters //------------------------------------------------------------------ SkipSpaces(inputLine, ref positionIndex); string variableName = ""; bool haveVariableNameFlag = GetVariableName(inputLine, ref positionIndex, ref variableName); //------------------------------------------------------------------ // Calculate the sign of the value. The sign is negated // if the equals sign has been encountered. //------------------------------------------------------------------ bool negativeFlag = m_equalSignInEquationFlag ^ m_negativeOperatorFlag ^ numberIsNegativeFlag; double value = 0.0; if (haveNumberFlag) { value = Convert.ToDouble(numberString); if (negativeFlag) { value = -value; } } else { value = 1.0; if (negativeFlag) { value = -value; } } //------------------------------------------------------------------ // If a variable was encountered then add to the aMatrix. //------------------------------------------------------------------ bool haveTermFlag = false; if (haveVariableNameFlag) { //-------------------------------------------------------------- // If either a number or a variable is found then a term was // found. //-------------------------------------------------------------- haveTermFlag = true; //-------------------------------------------------------------- // Each equation must have at least one variable. // Record that a variable was encountered in this equation. //-------------------------------------------------------------- m_atLeastOneVariableInEquationFlag = true; //-------------------------------------------------------------- // If this variable has not been encountered before then add // the variable to the variableNameIndexMap. //-------------------------------------------------------------- int variableNameIndex = 0; if (!variableNameIndexMap.TryGetValue(variableName, out variableNameIndex)) { // This is a new variable. Add it to the map. variableNameIndex = variableNameIndexMap.Count; variableNameIndexMap[variableName] = variableNameIndex; } aMatrix[m_equationIndex, variableNameIndex] = aMatrix[m_equationIndex, variableNameIndex] + value; } else if (haveNumberFlag) { //-------------------------------------------------------------- // If either a number or a variable is found then a term was // found. //-------------------------------------------------------------- haveTermFlag = true; //-------------------------------------------------------------- // Put the value in the B vector. //-------------------------------------------------------------- bVector[m_equationIndex] = bVector[m_equationIndex] - value; } else { haveTermFlag = false; SetLastStatusValue(LinearEquationParserStatus.ErrorNoTermEncountered, positionIndex); return(false); } //------------------------------------------------------------------ // There must be at least one term on each side of the equal sign. //------------------------------------------------------------------ if (haveTermFlag) { if (m_equalSignInEquationFlag) { m_termAfterEqualSignExistsFlag = true; } else { m_termBeforeEqualSignExistsFlag = true; } } //------------------------------------------------------------------ // Skip whitespace characters //------------------------------------------------------------------ SkipSpaces(inputLine, ref positionIndex); return(haveTermFlag); }
/// <summary> /// This function parses line that contains all or part of a simple /// linear equation. The equation contains terms separated by operators. /// The term can be a number, a variable, or a number and a variable. /// A term cannot be split between lines input to the parser method. /// The operators are either the plus character '+', the minus /// character '-', or the equal sign character '='. Numbers can have /// up to 15 digits, a decimal point, and an exponent of a power /// of 10 that follows the '^' character. /// </summary> /// <param name="inputLine">The input line of text to be parsed</param> /// <param name="aMatrix">The A matrix for the simultaneous equations. /// This is updated as each line of input is parsed. /// </param> /// <param name="bVector">The B vector for the simultaneous equations. /// This is updated as each line of input is parsed.</param> /// <param name="variableNameIndexMap">A map that stores the integer /// index for a variable using the variable name as a key.</param> /// <param name="numberOfEquations">A reference to an integer that /// will contain the number of equations when this method exits. /// </param> /// <returns>An enum of type LinearEquationParserStatus</returns> public LinearEquationParserStatus Parse(string inputLine, Sparse2DMatrix <int, int, double> aMatrix, SparseArray <int, double> bVector, SparseArray <string, int> variableNameIndexMap, ref int numberOfEquations) { //------------------------------------------------------------------ // Trim any space characters from the end of the line. //------------------------------------------------------------------ inputLine.TrimEnd(null); //------------------------------------------------------------------ // Assume success status. //------------------------------------------------------------------ int positionIndex = 0; SetLastStatusValue(LinearEquationParserStatus.Success, positionIndex); //------------------------------------------------------------------ // Skip whitespace characters //------------------------------------------------------------------ SkipSpaces(inputLine, ref positionIndex); //------------------------------------------------------------------ // Save the position of the first non-whitespace character. If // the first term is not found at this position then set the // error status to report that it is likely that the last // equation was not properly terminated. //------------------------------------------------------------------ m_startPosition = positionIndex; //------------------------------------------------------------------ // Separate the input string into tokens. // // Variables contains the letters A through Z and the underscore // '_' character. // // Operators include plus '+', minus '-', and times '*'. // // Delimiters include the equals sign '='. // // Numbers include the digits 0 through 9, the decimal point // (period character) '.', an optional exponent character which // is the letter '^', and up to two digits for the optional exponent. // // Check for sequences of terms and operators. // // Term: // <Space> <Sign> Number <Space> // <Space> <Sign> Variable <Space> // <Space> <Sign> Number Variable <Space> // // Operator: // <Space> Plus <Space> // <Space> Minus <Space> // <Space> Equals <Space> // //-------------------------------------------------------------- bool operatorFoundLast = false; while (positionIndex < inputLine.Length) { if (m_parserState == LinearEquationParserState.ParseTerm) { //------------------------------------------------------ // Skip whitespace characters //------------------------------------------------------ SkipSpaces(inputLine, ref positionIndex); if (positionIndex < inputLine.Length) { if (GetTerm(inputLine, ref positionIndex, aMatrix, bVector, variableNameIndexMap)) { m_parserState = LinearEquationParserState.ParseOperator; operatorFoundLast = false; } else { if (LastStatusValue == LinearEquationParserStatus.Success) { SetLastStatusValue(LinearEquationParserStatus.ErrorIllegalEquation, positionIndex); } break; } } else { break; } } else if (m_parserState == LinearEquationParserState.ParseOperator) { //------------------------------------------------------ // Skip whitespace characters //------------------------------------------------------ SkipSpaces(inputLine, ref positionIndex); if (positionIndex < inputLine.Length) { //------------------------------------------------------ // Check for plus sign, minus sign, or an equal sign. //------------------------------------------------------ if (GetOperator(inputLine, ref positionIndex)) { m_parserState = LinearEquationParserState.ParseTerm; operatorFoundLast = true; } else { if (LastStatusValue != LinearEquationParserStatus.Success) { if (positionIndex == m_startPosition) { SetLastStatusValue(LinearEquationParserStatus.ErrorIllegalEquation, positionIndex); } } break; } } } } // If an operator was found at if ((positionIndex >= inputLine.Length) && (positionIndex > 0) && (!operatorFoundLast)) { ResetForNewEquation(); numberOfEquations = m_equationIndex; } return(LastStatusValue); }