0

I want to maximize a function with constraints. When i use the following code i get: The index was outside the array

When i use the commented code it works, but what's the difference?

        for (int k = 0; k < 3; k++)
        {
            constraints.Add(new NonlinearConstraint(3, x => x[k] >= 0));
        };
        //constraints.Add(new NonlinearConstraint(3, x => x[0] >= 0));
        //constraints.Add(new NonlinearConstraint(3, x => x[1] >= 0));
        //constraints.Add(new NonlinearConstraint(3, x => x[2] >= 0));

        var cobyla = new Accord.Math.Optimization.Cobyla(function, constraints);
Fabian
  • 23
  • 3
  • Probably that some evaluation of `x => x[k] >= 0` is occurring when k==3 (k reaches 3 then the loop quits), like a LINQ deferred execution thing where evaluation of the LINQ occurs later (when the code has left the loop) – Caius Jard Jul 03 '20 at 21:25
  • What version of Visual Studio are you using? This was a known issue (not exactly a bug), but it was supposedly fixed back with C# 5 / Visual Studio 2012. https://stackoverflow.com/a/8649429/3043 – Joel Coehoorn Jul 03 '20 at 21:25
  • Thank you for the answers, I am using Visual Studio 2019 right now – Fabian Jul 03 '20 at 21:29
  • 1
    @JoelCoehoorn `for` loop behaviour was not changed, only `foreach` – Guru Stron Jul 03 '20 at 21:33

1 Answers1

0

It is because the lambda is called outside the loop by Cobyla.

There is a name to that I don't remember.

Think it is like an afterglow.

So the index after the loop is 3 and it it out of bound.

Hence you call three times the same lambda with index as 3...

But with the commented lines, you're good.

You can use ILSpy to see that.

I read few days ago that some last or next C# version changed or will change this behavior.

Based on Captured variable in a loop in C# you can write:

for (int k = 0; k < 3; k++)
{
  int i = k;
  constraints.Add(new NonlinearConstraint(3, x => x[i] >= 0));
};
  • 1
    Perfect this solved my problem and i understood the problem :) Thank you very much, have a nice weekend – Fabian Jul 03 '20 at 21:37
  • 1
    FYI this called capturing a variable over a closure. Also this is not going to be fixed for `for` loops but has been for `foreach` loops which now define the variable inside the loop scope instead of outside. – juharr Jul 03 '20 at 22:06