levenberg-marquardt icon indicating copy to clipboard operation
levenberg-marquardt copied to clipboard

parametrizedFunction constants

Open andcastillo opened this issue 5 years ago • 5 comments

The parametrizedFunction must accept a constant. I.e. all the other parameters that does not need to be fitted

function parametrizedFunction(params, constants) { }

andcastillo avatar Apr 15 '19 15:04 andcastillo

Can you give a clearer example with a real function to fit? I'm pretty sure this can be solved on your side with JavaScript features.

targos avatar Apr 16 '19 08:04 targos

function parametrizedFunction(params, c) { return (x) => c + f(params); }

I cannot or should not modify f. And c should be chosen from a finite set of possible values. Now, in my loop I have this: for (let c of [1,2,3,4...]) { ... let parametrizedFunction = function(params) { return (x) => c + f(params); } ... LM(data, parametrizedFunction ...) } That works, but require to define a function within a loop, and that "c" inside is crappy. In the Matlab LM version they have the constants

andcastillo avatar Apr 16 '19 13:04 andcastillo

That works, but require to define a function within a loop, and that "c" inside is crappy.

Actually, you don't need to define it there. You could easily use a "factory" function instead like this:

function getFixedFunction(...constants) {
  return function fixedFunction(...variables) {
    let result;
    // ...(use the constants & variables to compute the result)...
    return result;
  }
}

for (let c of [1, 2, 3, 4 /* ... */ ]) {
  // ...
  LM(data, getFixedFunction(c) ...)
}

In the Matlab LM version they have the constants

That may be more idiomatic for Matlab, but since JavaScript has better support for functional programming / "first class functions" it is possible to separate the concern regarding how the function is constructed (constants, etc.) from the LM implementation. I think keeping the API simple for this is a better design choice then trying to force a particular decomposition onto the user. For example, I cannot think of a function for which the existing call signature will not work, yet if we required the function to be in some particular form, say c1*x1 + c*x2 + ... I can think of plenty of examples where this would be difficult to work with. Plus having only one argument eliminates mistakes due to getting their order mixed up.

jacobq avatar Apr 16 '19 14:04 jacobq

I see. Nevertheless, the factory function used in this way is syntactic sugar for defining functions within a loop. My real concern is that there exist many complex function with many parameters, but usually you only want to optimize a subset of them. Second, I don't consider to separate the variables from the constants within an optimization process is idiomatic stuff. It is a real semantic differentiation of the things.

eliminates mistakes due to getting their order mixed up.

The function that have right to call parametrizedFunction is the LM, so there is only one person who can mix up those parameters.

As I say, It is working, but I consider including the constants can simplify many cases.

andcastillo avatar Apr 16 '19 15:04 andcastillo

Nevertheless, the factory function used in this way is syntactic sugar for defining functions within a loop.

How would having LM do that instead make things any different?

My real concern is that there exist many complex function with many parameters, but usually you only want to optimize a subset of them.

Exactly. The LM algorithm should only have to worry about the parts being adjusted, so having another portion of code deal with selecting which parameters are constant and which are not makes perfect sense. There are also certainly more ways to set things up than in my example, and the right choice will depend on the particular use case. In general I was trying to demonstrate how higher-order functions (similar to currying) can help improve code composability, making it easier to reuse across many different use cases.

jacobq avatar Apr 16 '19 16:04 jacobq