# Loop for minimizing functions with a varying number of arguments

I have to build a loop where each iteration consists in building a function to minimize. At each iteration, the number of arguments is variable. To start, I have two matrices:

``````
X=rand(150,100)
Y=rand(150,1)
``````

At each iteration I select randomly some columns of `X` to build my function.

``````
k=sample(1:size(X,2))
m=sample(1:size(X,2),k,replace=false)

``````

Let’s say that `k=6` columns were selected. I have then to build a function with `k=6` arguments:

``````using Optim
Xsub=X[:,m]
h(beta1,beta2,beta3,beta4,beta5,beta6)=-sum(Y.*Xsub*[beta1,beta2,beta3,beta4,beta5,beta6])+
sum(log.(1 .+exp.(Xsub*[beta1,beta2,beta3,beta4,beta5,beta6])))+(size(Xsub,2)+1)/2*log(2*pi)+1/2*sum([beta1^2,beta2^2,beta3^2,beta4^2,beta5^2,beta6^2])
f(betas) = h(betas...)
betasestim=optimize(f,zeros(size(Xsub,2)),method = ConjugateGradient(),autodiff = :forward,x_tol = 1e-7).minimizer

``````

That’s an example for one particular iteration. But how can I do to build such a function for each iteration, provided that the number `k` of selected columns is different at each time as they are randomly selected. How can I do to create the arguments `beta1, beta2, ..., betak` as they are different at each time? I also tried an approach of creating a unique function that will be called at each iteration, such as:

``````function funcoptim(arguments)

end
``````

where `arguments` can vary every time the function is called inside of the loop, but I’m stuck…

Look into macros.

@Joris_Pinkse Into macros?

Why not pass the vector of arguments as a single argument.

Ok myabe not, why not splatting the arguments?

``````h(betas...) = -sum(Y .* Xsub .* betas) +  sum(log.(1 .+ exp.(Xsub .* betas)))
+ (size(Xsub, 2)+1)/2*log(2*pi) + 1/2 * sum(betas .^ 2)
``````

Yes, but at each iteration the vector of arguments is different. For exemple, if `k=6` I have the vector `beta1,beta2,beta3,beta4,beta5,beta6` but if `k=50` the vector wil be `beta1,beta2, ..., beta50` (I don’t know how to create an argument with so many variables btw… ). I need all the components of the vector to appear as they are the arguments to minimize the function.

yeah sorry I realised that while you were typing. See my edited answer: use splats

Yes I just saw! I’ll try your suggestion and keep you in touch! Just one detail: I must multiply each row of `Xsub` with `betas`. It’s a matrix multiplication and not an element-wise multiplication. It shoud be `Xsub*betas` instead of `Xsub .* betas` as I had in my code.

It does not work I get a `ERROR: MethodError: no method matching exp(::Array{Float64,1})` error. Even with a simple case as

``````h(betas...)=(betas .- 1)^2
optimize(h,zeros(size(Xsub,2)),method = ConjugateGradient(),autodiff = :forward,x_tol = 1e-7).minimizer
``````

use

``````h(betas...)=(betas .- 1) .^ 2
``````

Are you really sure you need your function to have `k` arguments though? I seriously think you should be using a vector for this.

2 Likes

Yes… The number of arguments changes at each iteration. The number of arguments is indicated by `k`. And it doesn’t work even with `h(betas...)=(betas .- 1) .^ 2`. I get `ERROR: MethodError: no method matching -(::Array{Float64,1}, ::Int64)`.

I get `ERROR: MethodError: no method matching -(::Array{Float64,1}, ::Int64)` .

Then look for the line (it should be indicated in your stacktrace) where that error come from. There’s probabably a `v - 1` that should be `v .- 1` for some `v::Vector`.

Yes… The number of arguments changes at each iteration. The number of arguments is indicated by `k` .

Does it need to be that way though? I still don’t understand why you can’t just have a function of a single vector and have the length of that vector change in each iteration? This will likely be a lot more efficient than writing a function of 50 variables (in terms of compile time, runtime and writing time).

5 Likes

Ok I’ll check the error. Yes you’re right! It can be a vector whose length changes at each iteration. The important is to find the value of the vector which minimizes the function at each iteration because I need the minimizers.

1 Like

Ah I think I’m close to the solution with the single vector with varying length you proposed!