I have 3 codes as given in attachment. When I run the "main.m", it gives the following error:
Index in position 1 exceeds array bounds. Index must not exceed 1.
Error in ArGeo (line 17)
cosd(b(2, :)) .* cosd(b(1, :)); % x-component
Error in main>@(b)ArGeo(b,u,Noise)+penaltyTerm(b,u) (line 25)
[time,gBest,gBestScore]=WHO(20,100,lb,ub,dim,@(b) ArGeo(b,u,Noise)+penaltyTerm(b, u));
Error in WHO (line 47)
group(i).cost=fobj(group(i).pos);
Error in main (line 25)
[time,gBest,gBestScore]=WHO(20,100,lb,ub,dim,@(b) ArGeo(b,u,Noise)+penaltyTerm(b, u));
>>

 Réponse acceptée

Voss
Voss le 1 Mai 2024

0 votes

In WHO.m lines 45-48, you have
for i=1:Nfoal
group(i).pos=lb+rand(1,dim).*(ub-lb);
group(i).cost=fobj(group(i).pos);
end
where dim is 2, and lb and ub are each 1xdim vectors. Thus, group(i).pos is created as a 1xdim vector on line 46, and the error happens after fobj (which is @(b) ArGeo(b,u,Noise)+penaltyTerm(b, u)) is called on line 47, because inside ArGeo.m, input b, which is group(i).pos in WHO.m, is expected to have at least 2 rows:
kb = pi * [
cosd(b(2, :)) .* cosd(b(1, :)); % x-component
sind(b(2, :)) .* cosd(b(1, :)); % y-component
sind(b(1, :)) % z-component
];
That's the reason for the error.
As far as how to fix it, I suspect that lines 26-29 of WHO.m are not doing what's intended:
if size(ub,1)==1
ub=ones(1,dim).*ub;
lb=ones(1,dim).*lb;
end
Since ub and lb are each 1xdim vectors, you are multiplying each element of ub and lb by 1, which leaves them unchanged. Instead, I guess you want to replicate them so that they have exactly 2 rows (not dim rows), which could be done like:
if size(ub,1)==1
ub=ones(2,1).*ub;
lb=ones(2,1).*lb;
end
Then they are of size 2xdim, which seems like what's intended.

9 commentaires

Sadiq Akbar
Sadiq Akbar le 2 Mai 2024
Thanks a lot for your kind response. I did that changes and ran it but now it gives the following error:
Index exceeds the number of array elements. Index must not exceed 4.
Error in exchange (line 16)
bestgroup=Stallion(i).group(index);
Error in WHO (line 77)
Stallion=exchange(Stallion);
Error in main (line 25)
[time,gBest,gBestScore]=WHO(20,100,lb,ub,dim,@(b) ArGeo(b,u,Noise)+penaltyTerm(b, u));
>>
Voss
Voss le 2 Mai 2024
You're welcome! Since the original error is solved, please "Accept" this answer. Thanks!
The new error means that i or index is greater than 4 on the line
bestgroup=Stallion(i).group(index);
and that's a problem because (if it's i) Stallion has only 4 elements or (if it's index) Stallion(i).group has only four elements.
You can set a breakpoint (https://www.mathworks.com/help/matlab/matlab_prog/set-breakpoints.html) at that line and check the value of the variables.
If you're not sure what to do to fix it, please upload the file exchange.m (and any other m-files it needs to run), and I'll take a look.
Sadiq Akbar
Sadiq Akbar le 2 Mai 2024
Thanks a lot for your kind response. Sorry I had forgotten to upload the supporting files for WHO. Here are they attached now.
Important: Actually most of time I keep one row in all u vetros. So once again I have replaced the u vectors by a single row instead of two rows because when u has one row, then may be you solve it quickly. So I uploaded the main.m file also.
I hope now you will solve it very quickly because its easy for you but very difficulat for people like me.
Voss
Voss le 2 Mai 2024
Regarding the error
Index exceeds the number of array elements. Index must not exceed 4.
Error in exchange (line 16)
bestgroup=Stallion(i).group(index);
Error in WHO (line 77)
Stallion=exchange(Stallion);
Error in main (line 25)
[time,gBest,gBestScore]=WHO(20,100,lb,ub,dim,@(b) ArGeo(b,u,Noise)+penaltyTerm(b, u));
the first time exchange is run, when i is 1, this line
[value,index]=min([Stallion(i).group.cost])
produces an index value of 7. The array
[Stallion(i).group.cost]
is of size 1x12 because Stallion(1).group is a 1x4 struct array and each element of it contains a cost field which is 1x3. So, it's not appropriate to try to index Stallion(i).group with the index of the minimum element in [Stallion(i).group.cost].
Furthermore, Stallion(1).cost is a 1x3 vector, so comparing it with value like this
if value<Stallion(i).cost
means that the if condition is true only when value is less than all elements of Stallion(i).cost. Is that what you want to do?
In general, I recommend putting breakpoints in your code and making sure the sizes of various variables make sense and are as intended, as the code runs.
Sadiq Akbar
Sadiq Akbar le 2 Mai 2024
Actually the I don't understand the coding of WHO algorithm because I have downloaded it from the Mathworks site. However, the ArGeo.m is my function. Normally I have been using the u vector as having a single row but since it was giving error, that's why I put a semicolon inside u and made two rows in u. I thought that it will remve the error but in vain.
Further, if you run the ArGeo.m as a script alone, it works. for example I attach it here, you run it, it works but I don't don't know why it gives error with main.m?
Voss
Voss le 2 Mai 2024
Modifié(e) : Voss le 2 Mai 2024
OK. Since WHO is a File Exchange entry, forget what I said in my answer, and go back to the original code you downloaded from the File Exchange.
Your ArGeo assumes u and b have (at least 2 rows), so the u defined in your main needs to have (at least) 2 rows:
u_sets = {[-33 -40; 33 40], [-50 -60 -70; 50 60 70], [-20 -30 -42 -52; 20 30 42 52]};
I think ub and lb need to be the same size as u, so in main:
[n,dim]=size(u);
lb = -90*ones(n,dim);
ub = 90*ones(n,dim);
And I think the cost assigned to each Stallion needs to be a scalar, which your ArGeo returns a scalar but then a penalty term is added, which is not necessarily a scalar, so in main:
penalty = 100 * sum((x - desiredResult).^2,'all');
% ^^^^^^ sum over all elements
With those three changes in main, the code runs, at least past the WHO part, until the displaying the results part, where an error with concatentating a character vector with num2str(u) occurs, because u has multiple rows. You can use mat2str(u) instead, to get around that. After that, the code completes.
As to whether the results make any sense, I haven't the foggiest idea, since I have no references for the WHO algorithm or any explanation of the assumptions made in that code.
I've attached an updated main.m with all of those changes.
Sadiq Akbar
Sadiq Akbar le 3 Mai 2024
Thanks a lot for your kind response. Yes, it runs but gives absolutely wrong results. When I run the main, it should give me nearly the values of u. As you can see the 1st set of u inside main is having four values i.e.,
[-33 -40;33 40], so after running the main, it should return me these values i.e., [-33 -40;33 40]. Likewise, the 2nd set of u inside main is : [-50 -60 -70;50 60 70], so after running the main, it should retun me these values and so on. But when I ran your modified main, the code runs but it gives me these values:
[0.00032681 0.00032681] instead of [-33 -40;33 40]
[-0.0033306 -0.0033306] instead of [-50 -60 -70;50 60 70]
[0.0096308 0.0096308] instead of [-20 -30 -42 -52;20 30 42 52]
So I don't want to run just the code but rather I want to get these results.
Voss
Voss le 3 Mai 2024
I don't know.
Sadiq Akbar
Sadiq Akbar le 4 Mai 2024
Dear Voss my problem is not solved but looking at your time that you spared for my problem, it's precious, so I accept your answer.
Regards,

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Startup and Shutdown dans Centre d'aide et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by