I am testing the Extreme Optimization C# library, precisely the nonlinear system solvers. As an example I find that I have to pass the solver the nonlinear system in the following shape:
Func<Vector, double>[] f = {
x => Math.Exp(x[0])*Math.Cos(x[1]) - x[0]*x[0] + x[1]*x[1],
x => Math.Exp(x[0])*Math.Sin(x[1]) - 2*x[0]*x[1]
};
The problem is that the system I try to solve cannot be specified at design time. It is a nonlinear system composed by the load flow equations to solve an electrical circuit of altern current (AC). The equations are composed by a number of variables that depend of the number of nodes in the grid, which is especified by the user, the equations are these:
So basically I have 2 equations per node, this is 2*n equations, which cannot be composed in a single line bacause they depend of i,j indices, therefore I have to have 2 nested for loops to create the P and Q equations.
Is there a way to create Func<Vector, double>[] f = { equation system of variable lenght };
?
I have seen the post Creating a function dynamically at run-time, but it doesn't answer my quetion (I believe)
//************************EDIT**************************************
The creation of the equations is something like this:
For (int i=0; i< n; i++){
double A=0.0;
double B=0.0;
For (int j=0; j< n; j++){
A+= G[i,j]*Math.Cos(Theta[i,j]) + B[i,j]*Math.Sin(Theta[i,j])
B+= G[i,j]*Math.Sin(Theta[i,j]) + B[i,j]*Math.Cos(Theta[i,j])
}
P[i]=V[i]*A;
Q[i]=V[i]*B;
}
Ofcourse A and B contain the variables, and this loop formulation as it is makes little sense.
Thanks in advance.
You're passing a function array, so it should be pretty easy to do what you want:
Func<Vector, double>[] funcs = new Func<Vector, double>[howeverManyYouWant];
for (var i = 0; i < howeverManyYouWant; i++)
{
var someConstant = 0.1f * i; // You need to define "constants" in scope
funcs[i] = x => Math.Exp(x[0])*Math.Cos(x[1]) - x[0]*x[0] + x[1]*x[1];
}
You can then pass the array as needed.
If you can't determine the size of the array in advance, you can use List<Func<Vector, double>>
instead of an array, and then just call ToArray()
on it when it's ready.
EDIT: I've just realized you aren't actually passing Expression<Func<...>>
- this makes everything all that much simpler, since you can use a for cycle inside the function you're passing:
List<Func<Vector, double>> funcs
= new List<Func<Vector, double>>(howeverManyYouWant * 2);
for (var i = 0; i < howeverManyYouWant; i++)
{
// P[i] equation
funcs.Add
(
x =>
{
var a = 0d;
for (var j = 0; j < howeverManyYouWant; j++)
{
a += G[i, j] * Math.Cos(Theta[i, j]) + B[i, j] * Math.Sin(Theta[i, j]);
}
return x[i] * a;
}
);
// Add your Q[i] equation here the same way.
funcs.Add(...);
}
You'll have to modify it to really fit your case, because I have no idea how the func array is called, what's passed to the function, what you want to have as a constant or a variable etc. (I've just replaced V
with x
in this example), but it does show the basic idea.
Of course you'll want to refer to x
somewhere, otherwise you could obviously just precompute the value - but that would hardly be helpful :)
Given that, I can't know if that's what you're after. You'll have to specify what should be considered a constant, what's being passed to the functions etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With