Reputation: 197
I am trying to have some fun by converting some java into c#, I have the following code from java.
public void calculate() {
UnivariateFunction forceBalance = (double x) -> {
return Mu - k1 * fcu * b * x * (d - k2 * x);
};
BrentSolver biSolver = new BrentSolver(1e-6);
x = biSolver.solve(1000, forceBalance, 0, d / 2, 1);
As = Mu / (gamma_r * fy * (d - k2 * x));
}
No all i can find in c# is that seems to solve this MathNet.Numerics as this contains RootFinding.Brent.FindRoot.
I found other stuff that could solve this however I do not have $900.
Here is what i have come up with however i think I might be missing something as my knowledge regarding delegates isn't the best.
class Program
{
public static double Mu = 100e6;
public static double K1 = 0.45 * (1 - (Math.Sqrt(fcu) / 52.5));
public static double fcu = 30.00;
public static double b = 300.00;
//public static double c = 0.00;
public static double d = 500.00;
public static double k2 = (Math.Pow(2 - Math.Sqrt(fcu) / 17.5, 2) + 2) / (4 * (3 - (Math.Sqrt(fcu) / 17.5)));
static void Main(string[] args)
{
Calculate();
}
public static void Calculate()
{
Func<double, double> abc = x => Mu - K1 * fcu * b * x * (d - k2 * x);
var a = MathNet.Numerics.RootFinding.Brent.FindRoot(abc, 0, 10000, 1e-6);
Console.WriteLine();
Console.ReadLine();
}
}
Running this gives me the following error: failed, exceeded the number of iterations allowed or there is no root within the provided bounds.'
Now i am assuming that this is because the func isn't resolving x.
Am i missing something?
Also please take note that this is way above my skill level but I am trying to improve.
Upvotes: 1
Views: 139
Reputation: 321
Input Values
Firstly if your question is about input values, look at the answer posted by soton. You may be using the wrong FindRoot input values. Brent Math.Net.
double FindRoot(Func<double, double> f, double lowerBound, double upperBound, double accuracy, int maxIterations)
Delegates
Now, with your question I believe you are asking about how delegates are handled in C# vs Java. (I won't spoil your fun).
A delegate is the placeholder for a method which matches a specified signature (a reference to a method).
The following is an example of a variable which matches the delegate type of Func<int, bool>
meaning it accepts an integer (x) as a parameter and return a boolean.
The way this example is declared (with an anonymous method body) is known as a Lambda Expression.
Func<int, bool> greaterThanZero = (int x) =>
{
if (x > 0)
return true;
else
return false;
};
Here is the same again, but the delegate variable is assigned from a method declaration.
Func<int, bool> greaterThanZero = SomeGreaterThanZeroMethod;
How do we call a delegate? We Invoke it! e.g.
bool isGreater = greaterThanZero(5); // should be true
bool isGreater = greaterThanZero.Invoke(-1); // should be false
In many situations you will want to make sure the method body is not null e.g.
bool isGreater = false;
if (greaterThanZero != null)
isGreater = greaterThanZero.Invoke(-1);
Or using the fancy new Null-Conditional Operator (?)
bool isGreater = greaterThanZero?.Invoke(-1);
There is more here than you could possibly sum up in an answer. Some resources: https://www.tutorialspoint.com/csharp/csharp_delegates.htm https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions
Upvotes: 1
Reputation: 401
Your isssue is neither caused by MathNet Numerics implementation of Brent method nor by improper delegates usage. You get this error because there are both roots in fact on the interval provided and evaluation of the given function for both interval ends results in positive numbers i.e. 100000000 and 162453965327 while Brent method requires them to differ in sign. Actual roots for this particular equations are about in 51.8 and 1057.15 so your input interval should contain a point between these two.
To be honest I am a bit surprised why Java implementation works for this set of parameters. Are you sure you have not mistyped anything during conversion?
Upvotes: 0