Function with multiple arguments with all subsets of variables

I have to construct a set of functions that I want to optimize. The set consists of functions with all subsets I can build with p variables. If p is small, that’s easy. For example, with p=2, I can build 2^2-1=3 functions, one for each subset of variables (I excluded the empty subset):

f(x)=2*x^2+1
f(y)=2*y^2+1
f(x)=2*x[1]^2+2*x[2]^2+1

But if I have p=6 variables, how can I construct all the 2^6-1=63 possible functions to optimize without having to create 63 functions? I thought about creating an Array like x=[x[1],x[2],x[3],x[4],x[5],x[6]] and then building all the functions, setting to 0 all the variables that are not present in the function corresponding to the selected subset.

Functions of what form exactly? Looking at your code it’s functions of the form 2x^2 + 2y^2+2z^2?

I think something like this

function one_func(x)
    # x nees to be iterable of bool
    return function(x1::AbstractVector)
        res = 1
        for (i, doit) in enumerate(x)
            if doit
                res += 2x1[i]^2
            end
        end
        res
    end
end

function func_factory(len)
    seed = ((false, true) for i in 1:len)
    collect(one_func(x) for x in Iterators.drop(Iterators.product(seed...),1))
end

funs = func_factory(2)
funs[1]([1, 2])
funs[2]([1, 2])
funs[3]([1, 2])


funs6 = func_factory(6)

[fun([1,2, 3, 4, 5, 6]) for fun in funs6]

You can also use macros for even better results. For this is sufficient for me.

1 Like

Sorry for the delay. I went to bed a few minutes after my post… Yes exactly that’s the form of the function!

Ah I think this solution will do the trick, because I have another similar problem to treat with a more complex function! I will post this more challenging problem :wink:

Here is a more challenging problem with p=5 variables, to see if the proposed solution can be adapted. I have 2 coefficient matrices, say

X=rand(10,5) and Y=rand(10,1),

where each column of X represents each variable. I must construct the following function:

h(betak)=-sum([Y[i]*transpose(X[i,:])*[betak[1],betak[2],betak[3],betak[4],betak[5],betak[6]] for i in 1:size(X,1)])+
          sum([log(1+exp(transpose(X[i,:])*[betak[1],betak[2],betak[3],betak[4],betak[5],betak[6]])) for i in 1:size(X,1)])+
          length(betak)/2*log(2*pi)

Basically, the function has to multiply each row of X by the subset of variables selected. In this example, I have the whole subset of variables [betak[1],betak[2],betak[3],betak[4],betak[5],betak[6]] but I’d like to build the same function for each subset. For example, if the subset is [betak[1],betak[4],betak[5]] I wonder how I can write the same function for that subset and for all other subsets. I thought about using the same code but with [betak[1],0,0,betak[4],betak[5],0]. However, I’m not sure how to do it… I don’t want to write all the 2^5-1=31 possible functions…

Feels like u can change this line to output false where u don’t want. E.g.

keep = [1, 4, 5]
seed = (i in keep ? (false, true) : (false,) for in in 1:len)

Now u gotta figure out how to generate all possible keep. Look into the Combinatorics.combination function and see what u can figure out. To get you started:

using Combinatorics
collect(combinations(1:6, 3))
1 Like

Thanks! Yes I already have all the combinations with Combinatorics :slight_smile: