Tricky optimisation problem of array

I am trying to find the optimum code pattern of an array X = {X(1), X(2), X(3)... X(10)} where the optimum pattern is given by the same solution of, time = ln(p(k)/q(k)) for each step where p(k) = X(k), k = 1:10 and q(k) = p(k+1) + 1 + sum(p(i)), where i=k+2.
For example the optimum solution for a 10 code pattern is X = {238 125 68 37 20 11 5 4 2 1} which gives time ~= 2.2 for each step (where q = {24 13 7 4 2 3 0 0 0 0}). I want to write code that will find this optimum solution.
I have code that finds the optimum solution starting with just 6 codes however I already have many nested for loops. Is there a better to do this without using many nested for loops?
To simplify the search range the starting point of each code will be around +/-30 of the optimum solution and the last 3 codes will always be 4,2,1.
M = 6;
k = 1;
x = 1;
y = 1;
z = 1;
p = [16 8 5 4 2 1 0]; % dummy 0 added as index goes out of bounds otherwise
for x = x:10
for y = y:10
for k = k:M
q(k,z) = -p(k+1) + 1 + sum(p(1,k+2:end));
time(k,z) = log(p(k)/q(k));
k = k + 1;
end
k = 1;
p(2) = p(2) + 1;
y = y + 1;
z = z + 1;
end
k = 1;
y = 1;
p(2) = 11;
p(1) = p(1) + 1;
x = x + 1;
end

Answers (1)

I can't really answer your optimisation question because I don't understand what you're trying to optimise. Note that given:
X = [238 125 68 37 20 11 5 4 2 1]
then per your definition of q in the code you've shown:
q = [-X(2:end) + 1 + [cumsum(X(3:end), 'reverse'), 0], 0] %no need for loop
which does indeed results in q = [24 13 7 4 2 3 0 0 0 0]. However:
>>log(X./q)
ans =
2.2942 2.2634 2.2736 2.2246 2.3026 1.2993 Inf Inf Inf NaN
There's nothing constant about these values. So what is the goal?
What I can say for sure is that your optimisation code does not do any optimisation. From the point of view of p, your whole code is equivalent to these two lines:
p(2) = 11;
p(1) = p(1) + 10;
The y and k loops have absolutely no effect on p and the x loop only effect is to set p(2) to 11 and increase p(1) by 10.
A few comments about your code:
1) Loop indexing
for x = x:10
Do not use the same variable name for the loop variable and for the bounds. That is just asking for troubles. You're allowed to use names with more than one letter. How about naming the bound xstart?
xstart = 1;
for x = xstart:10 %so much safer and easier to understand
2) vector indexing
q... = p(k+1) + ... p(1, k+2:end)
In the same equation you use linear (1D) indexing, suggesting that p is a vector, and subscript (2D) indexing, suggesting that p is a matrix. Be consistent, p is a vector, use linear indexing everywhere:
q(k,z) = -p(k+1) + 1 + sum(p(k+2:end));
Of course as I've shown above, the loop to calculate q is not needed if you use cumsum.
3) index incrementation in loop
for k = k:N %do not use the same variable name for loop index and bounds!
...
k=k+1
end
The k=k+1 has absolutely no effect. You could have written k=k+1000000 and have exactly the same result. As soon as the loop hits the end, k is the next value in the second k:N regardless of what value you've assigned to it

4 Comments

Thanks for your comment you have been a big help so far. I will try to explain my question differently. Originally I have:
X = [256 128 64 32 16 8 4 2 1]
The X values are actually capacitor values and ln(p/q) is the settling time.
By adding in an extra step (this step may be added anywhere), and slightly changing the capacitor values the settling time can be improved (note: q=0 in the original X - there is another way to calculate settling time for that).
What I want to know is what is the optimum value for each capacitor so that the settling time is the smallest for each step. I don't want 1 large settling time and all others very small. I want them to be all roughly the same but as small as possible. In the example i've given the optimum solution is
X = [238 125 68 37 20 11 5 4 2 1]
Which results in a settling time of about 2.2 for each step.
I'm trying to write code that finds this optimum solution.
Hope that clears some things up. Thanks again for your help.
P.S. is cumsum with 'reverse' option a new feature in Matlab? As I am using R2012a and keep getting an error when using this.
Yes, the 'reverse' option was introduced in R2014b. You can use
fliplr(cumsum(fliplr(X(3:end))))
instead
Guillaume
Guillaume on 23 Mar 2016
Edited: Guillaume on 23 Mar 2016
'... X = [238 125 68 37 20 11 5 4 2 1] which results in a settling time of about 2.2 for each step.'
If the settling time is log(X./q), then not really. It indeed results in value around 2.2 for the first 5 values but 1.2 for the 6th and infinity thereafter.
We can assume that the last 3 values [4,2,1] don't change so as a result q=0 so settling time is infinity. It is ignored as the settling time in this case is negligible as the step between each step is very small. These steps just need to be included so that q is calculated correctly for the other steps. Thanks again for your help.

Sign in to comment.

Asked:

on 23 Mar 2016

Commented:

on 24 Mar 2016

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!