1

Say I have an external library that computes the optima, say minima, of a given function. Say its headers give me a function

double[] minimizer(ObjFun f)

where the headers define

typedef double (*ObjFun)(double x[])

and "minimizer" returns the minima of the function f of, say, a two dimensional vector x.

Now, I want to use this to minimize a parameterized function. I don't know how to express this in code exactly, but say if I am minimizing quadratic forms (just a silly example, I know these have closed form minima)

double quadraticForm(double x[]) {
    return x[0]*x[0]*q11 + 2*x[0]*x[1]*q12 +  x[1]*x[1]*q22
}

which is parameterized by the constants (q11, q12, q22). I want to write code where the user can input (q11, q12, q22) at runtime, I can generate a function to give to the library as a callback, and return the optima.

What is the recommended way to do this in C?

I am rusty with C, so asking about both feasibility and best practices. Really I am trying to solve this using C/Cython code. I was using python bindings to the library so far and using "inner functions" it was really obvious how to do this in python:

def getFunction(q11, q12, q22):
    def f(x):
        return x[0]*x[0]*q11 + 2*x[0]*x[1]*q12 +  x[1]*x[1]*q22
    return f
// now submit getFunction(/*user params*/) to the library

I am trying to figure out the C construct so that I can be better informed in creating a Cython equivalent.

akka
  • 23
  • 5
  • 2
  • @Olaf - I don't understand your edit. I specifically phrased the question in a C form, with code. The Cython part was just to give context. Why would you edit the C flag out? – akka Mar 19 '17 at 04:44
  • Why did you tag it as Cython? You use a snippet of it as pseudocode. This isn't a question about Cython, so it shouldn't have that tag. – Nic Mar 19 '17 at 05:17
  • Also, there's no way in C to do that, because there are no closures (which is what you're looking for). That's something only higher-level languages have. See [this](http://coliru.stacked-crooked.com/a/5a7f9bd08461daa6). – Nic Mar 19 '17 at 05:24
  • Removed Cython tag. – akka Mar 19 '17 at 12:18
  • @QPaysTaxes There are ways to do this in C, of course. Problem is they are opinion based and depend in the context. OP: I removed the C tag because you mentioned you want finally use Cython, which - as a diffeent language - provides other means than C. You should first pick your language, then work on a solution. – too honest for this site Mar 19 '17 at 15:41
  • @Olaf Not the exact thing that is being asked about. It works in Cython because functions in Cython aren't the same as functions in C; they're really just objects which can have some fancy syntax sugar on them. – Nic Mar 19 '17 at 15:45
  • @akka See my comment above -- the way Cython does it is by transforming the function into an object which just happens to accept `()` put on the end of it to do something, and stores the scope it was created in so you can reference local variables in it. You'll have to do the equivalent to do the same in C, and at that point you'll be rewriting Cython. There's no reason to figure out the C construct, as long as you know what the Cython code does. – Nic Mar 19 '17 at 15:47
  • @QPaysTaxes Not sure what you mean. I did not talk about Cython, but C in the first sentence. – too honest for this site Mar 19 '17 at 15:47

1 Answers1

-1

The header defines the prototype of a function which can be used as a callback. I am assuming that you can't/won't change that header.

If your function has more parameters, they cannot be filled by the call.
Your function therefor cannot be called as callback, to avoid undefined behaviour or bogus values in parameters.
The function therefor cannot be given as callback; not with additional parameters.

Above means you need to drop the idea of "parameterizing" your function.

Your actual goal is to somehow allow the constants/coefficients to be changed during runtime.
Find a different way of doing that. Think of "dynamic configuration" instead of "parameterizing".
I.e. the function does not always expect those values at each call. It just has access to them.
(This suggests the configuration values are less often changed than the function is called, but does not require it.)

How:
I only can think of one simple way and it is pretty ugly and vulnerable (e.g. due to racing conditions, concurrent access, reentrance; you name it, it will hurt you ...):

  • Introduce a set of global variables, or better one struct-variable, for readability. (See recommendation below for "file-global" instead of "global".)
  • Set them at runtime to the desired values, using a separate function.
  • Initialise them to meaningful defaults, in case they never get written.
  • Read them at the start of the minimizing callback function.
  • Recommendation: Have everything (the minimizing function, the configuration variable and the function which sets the configuration at runtime) in one code file and make the configuration variable(s) static (i.e. restricts access to it this code file).

Note:
The answer is only the analysis that and why you should not try paraemeters. The proposed method is not considered part of the answer; it is more simple than good.
I invite more holistic answers, which propose safer implementation.

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • Thanks, this is in fact what I converged to. I agree with you about all the vulnerabilities. – akka Mar 22 '17 at 03:34
  • And indeed, this is for the specific situation where the code implementing the header is simply not available to me and all I have is the header (and I cannot modify it). – akka Mar 22 '17 at 03:34