Algorithm Flow Control
Algorithm Flow Control
Algorithms are rarely linear. In numerical analysis, we must make decisions based on error thresholds and repeat operations until a solution converges. Flow control allows us to dictate the path our code takes using conditional logic and iterative loops.
1. Conditional Logic (if-else and switch)
Decisions in C# are handled primarily by if and switch statements. While if is perfect for range-based checks (like error tolerances), switch is ideal for choosing between discrete “modes” or “states” of an algorithm.
// if-else: used for logical ranges
double residual = 1e-5;
if (residual < 1e-6) { /* Converged */ }
// switch: used for distinct algorithm modes
string solverType = "Linear";
switch (solverType)
{
case "Linear": /* Use Direct Solver */ break;
case "NonLinear": /* Use Newton-Raphson */ break;
default: /* Use Default */ break;
}
2. Iterative Loops
Loops allow us to repeat a block of code. For numerical methods, the for loop is king when we know the number of iterations, while the while loop is used when we wait for a specific condition to be met.
[Image comparison of for-loop, while-loop, and foreach-loop structures]
Loop Type |
Best Use Case |
Key Characteristic |
|---|---|---|
for |
Stepping through matrices with an index. |
Precise index control. |
foreach |
Iterating over all nodes in a mesh. |
Read-only and safe. |
while |
Running a solver until convergence. |
Condition-based exit. |
do-while |
When the first iteration must occur. |
Post-condition check. |
Examples
Example 1 : The If-Condition: Safety Checks
Before performing a division in a numerical formula, such as normalizing a vector, it is vital to ensure we aren’t dividing by zero. An if statement acts as a “Guard Clause” to keep the solver stable.
double determinant = 0.00000001;
if (Abs(determinant) < 1e-12)
{
Console.WriteLine("Warning: Singular Matrix detected.");
}
else
{
double inverse = 1.0 / determinant;
Console.WriteLine($"Inversion successful: {inverse}");
}
Ouput
Inversion successful: 100000000
Example 2 : The Switch-Condition: Solver Selection
In a multi-physics application, you might need to switch between different integration schemes. The switch statement makes this choice clear and organized compared to a long chain of if-else blocks.
int methodCode = 2;
switch (methodCode)
{
case 1:
Console.WriteLine("Executing Forward Euler...");
break;
case 2:
Console.WriteLine("Executing Runge-Kutta 4th Order...");
break;
default:
Console.WriteLine("Falling back to Static Analysis.");
break;
}
Ouput
Executing Runge-Kutta 4th Order...
Example 3 : The While-Loop: Convergence Monitor
A while loop is the heartbeat of iterative methods. In this example, we simulate a cooling process where we keep calculating the temperature until it reaches the ambient environment temperature.
double temperature = 100.0;
double ambient = 25.0;
int seconds = 0;
while (temperature > ambient + 0.1)
{
temperature -= (temperature - ambient) * 0.1; // Cool by 10%
seconds++;
}
Console.WriteLine($"Cooled to {temperature:F2}°C in {seconds} seconds.");
Ouput
Cooled to 25.10°C in 63 seconds.
Example 4 : The Foreach Loop: Property Calculation
When you need to perform an operation on every element in a collection, like calculating the total mass of all elements in a structural model, foreach is the most readable choice because it eliminates index management.
double[] elementMasses = { 5.2, 3.8, 4.1, 6.0 };
double totalMass = 0;
foreach (double m in elementMasses)
{
totalMass += m;
}
Console.WriteLine($"Total System Mass: {totalMass}");
Ouput
Total System Mass: 19.1
Pro-Tip: Nested Loops
When working with 2D Matrices, you will often nest a for loop inside another. Remember that C# stores arrays in row-major order; iterating through rows in the outer loop and columns in the inner loop is significantly faster due to CPU cache optimization.