What is the best way to generate a function based on the other function definition?

Let’s say I have a function

function compute(x::Vector, y::Vector)
     return (x' * y) / sum(y)

Both x and y are vector with 0 or 1 values on each cell.

Based on this definition, I want to automatically generate a function, where for the variable in the denominator (y), I created a matrix Y, the rest variables remain to be vectors. The generated function should be something like:

function compute_generated(x::Vector, Y::Matrix)
    n = size(Y, 1)
    result = 0
    for i = 1:n 
         result += x' * Y[:,i] / i
    return result

What is the best way to perform this task?
I took a look at the Julia manual about macro and @generated function, but I am still confused about if the concept can be applied to the task.


I don’t understand how the two functions are related — in the first one the denominator is sum(y), in the kernel of the second one, i.

Generally, if you want to reduce a collection using a bivariate kernel function, look at mapreduce & friends. Generating a function from the source code of another functions is almost surely the wrong approach for what you are trying to do.

1 Like

I suspect this can be done with a macro, since the macro could look at the function you defined, break it apart and create a “different” function.

1 Like

I don’t know if this is what you are after but take a look at the mapslices function to apply a function to slices through a matrix.

I have some rules that translate one function to another. For examples:

  • only sum(x) and/or sum(y), and other linear manipulation on those are allowed in the denominator.
  • If sum(x) appears on the denominator, I need to to write a generated function that accept a matrix X. If it doesn’t appear, then the function should accept a vector x.

The goal is to create a library that make this process automatic, i.e. given someone write the original code, the library should automatically generate the transformed function.

Yea. it looks like macros is the right way to do this.

1 Like