0

I have a problem with proper design of partial function application with changing bound variables.

Imagine I have some balancing equation

f(x_1,...,x_n)=0

Then I put there all the variables except for x_k (k changes!), getting the function

g(x_k)=f(x_1=X_1,...,x_k,...,x_n=X_n)

Then I put it in some solver and get the solution for x_k. Just a few lines of code for illustration:

Func<double,double,double> f;
Func<double,double> g;
f = (x,y) => x - y;
g = (z) => f(10,z); // hier is the binding of the 1-st parameter hard-coded,
//but must be some way to choose which parameter to bind
double solution = solve(g);

In some way I need to pass an array of length n-1, the number k to let free and build a new function g on the fly. How would you proceed?

p.s. if possible, n should be also variable, however, to my understanding it would be a big leap in code/design complexity. If you have a strong opinion on this point, please validate my understanding.

Max Li
  • 5,069
  • 3
  • 23
  • 35
  • this sounds very similar to currying [link](http://stackoverflow.com/questions/411572/proper-currying-in-c-sharp) I haven't tried it in C# so not sure how difficult this would be – McShep Mar 24 '15 at 10:48
  • This is possible but always *hacky* - you would either need reflection and need to emit code or something similar - do you want to write a CSP solver? In this case you will not be happy using `Func<...>` in the long run - you might want to write your own abstraction for functions instead (some that you can manipulate without *hacking*) – Random Dev Mar 24 '15 at 10:48
  • PS a very *simple* alternative would be to pass in a key/value-pair for your fixed `x_i` - and always give back a function with a single argument that will add the **missing** key ;) – Random Dev Mar 24 '15 at 10:52
  • 1. in proper currying link, the answer is about fixed bound variables. 2. A key-value pair would be too long if n is big enough. 3. I don't want to write a CSP solver, I want to produce an equation with 1 variable [g(x)=0] and put it in some root-finding algorithm – Max Li Mar 24 '15 at 10:58

1 Answers1

1

Crude, but just the seed for an idea:

Func<int,double,double> g;
g = (i,z) => (i==0) ? f(10,z) : (i==1) ? f(z,10) : etc

A more flexible and complicated suggestion:

Func<double[],double> f;
Func<int[],double[],double> g;
g = (i,d) => f(i.Select( x => d[x]).ToArray());

Somewhere between the two:

Func<int,double,double[],double> g;
g = (k,c,d) => f(d.Select( (i,x) => (i!=k) ? x : c).ToArray());
Graham
  • 799
  • 2
  • 5
  • 14
  • Also: `Func f; Func g; g= (i,d) = f(i.Select( x => d[x]).ToArray())` – Graham Mar 24 '15 at 12:18
  • I'd say that the current solution rather leads astray. Imagine, n=20, then you have to write down 20 conditions. This is exactly the step that I want to get abstracted out/automated. Your comment looks promising, I don't see at the moment how g becomes the function of 1 variable. Could you elaborate on this and put it in the answer if it works out at the end? – Max Li Mar 24 '15 at 14:47
  • Not sure I fully understand the original problem. Surely there must be a second parameter to indicate k, otherwise it will be hard-coded like your simple example. The use of arrays means n is variable, but gives you more flexibility than I think you need. Perhaps this is better: `Func g; g = (k,c,d) => f(d.Select( (i,x) => (i!=k) ? x : c).ToArray())` – Graham Mar 24 '15 at 15:52
  • Probably, it also works. As for me, I'm consent with following option: Func f; Func g; f = (arr) arr[0] - arr[1]; double[] input; g = (x) => f(input.Select(y=>y==null? x: y).ToArray()); Then it works both on input=[10,None]; and on input=[None,10] You could put this or some of your solution from this direction into your answer and I'll accept it. – Max Li Mar 24 '15 at 16:30