I have never come across this need before. I think maybe with meta-programming it is possible, but I have never done that before.
I have a function which takes an integer input nknots
. For every increase in nknots
by one, I need to add one more outer while
loop to the code than was there for the original value. (I also need to add one more line of code per nknot
with the current version, but I think this could be handled by an interior for
loop.) So far, I have been hard-coding a pseudo-method for every possible value of the integer behind if
statements. However, I would like to make the code generic so that it can take any integer value larger than 2. The code looks very uniform with all the hard-coded numbers easy to turn into n
’s, but I don’t know how to add the outer while
loops in a loop.
I need help replacing the portion of the code below inside the if
statement with something generic. If nknots==3
, only the innermost while
loop should be used. If nknots==4
, only the inner two while
loops should be used. If nknots==6
, an outer while
loop should be added resembling the others. Ad infinitum.
using ElasticArrays
# Computes all possible knot locations on a dataset with `il` number of points, for a minimum segment length of `ilsegmin` and `nknots` number of knots.
function allknots(il::Int,ilsegmin::Int,nknots::Int)
# Initialize first knot combination
knots=ElasticArray{Int}(undef,nknots,1) # Create data storage structure for knots
j=1 # Possible knot location counter
knots[1]=1
for n=2:nknots-1
knots[n]=knots[n-1]+ilsegmin-1
end
knots[nknots]=il
if nknots==5
# Determine all remaining knot combinations
while knots[nknots-3,j] < il-3*ilsegmin+3 # Move thrid from last knot incrementally
while knots[nknots-2,j] < il-2*ilsegmin+2 # Move second to last knot incrementally
while knots[nknots-1,j] < il-ilsegmin+1 # Move last knot incrementally
j+=1
append!(knots,knots[:,j-1])
knots[nknots-1,j]=knots[nknots-1,j]+1
end
j+=1
append!(knots,knots[:,j-1])
knots[nknots-2,j]=knots[nknots-2,j]+1
knots[nknots-1,j]=knots[nknots-2,j]+ilsegmin-1
end
j+=1
append!(knots,knots[:,j-1])
knots[nknots-3,j]=knots[nknots-3,j]+1
knots[nknots-2,j]=knots[nknots-3,j]+ilsegmin-1
knots[nknots-1,j]=knots[nknots-2,j]+ilsegmin-1
end
end
return knots
end
allknots(12,3,5)
5×20 ElasticArray{Int64,2,1,Array{Int64,1}}:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 5 5 5 6
5 5 5 5 6 6 6 7 7 8 6 6 6 7 7 8 7 7 8 8
7 8 9 10 8 9 10 9 10 10 8 9 10 9 10 10 9 10 10 10
12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12