# 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

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`