Info
This question is closed. Reopen it to edit or answer.
Vectorization conversion issues for matrix computations
1 view (last 30 days)
Show older comments
This is my first attempt to increase the speed of my already working simulation but I am running into some problems. For this post I will only focus on one file, I will take the lessons learned here and apply them to the other files myself. I do apologize for the long post but I did not want to leave anything out. I have read many post on this matter but I have not been able to complete the conversion. Any advise would be of great help. Thank you all in advance!
Problem I have working code that is written with loops. My main data matrix (flock) is a nX3X2 matrix with n know at the start of the program. I am wanting to convert the following code:
% --- loop through the flock
for i = 1 : flock_size
agent_influence = [0,0];
obstacle_influence = [0,0];
% --- Calculate Influence From Agents --- %
index = calc_nearest_agent(i,flock,flock_size,range_sensing,range_collision);
if index == -1
agent_influence = [0,0];
else
if calc_a2a_distance(flock(index,1,:),flock(i,1,:)) < range_agent_repulsion
agent_influence = [0,0];
else
agent_influence = [(flock(index,1,1)-flock(i,1,1)),(flock(index,1,2)-flock(i,1,2))];
end
end
% --- Calculate Influence From Environment --- %
obstacle_influence = calc_obstacle_vector_range(flock(i,1,:),environment,sensing_range,flock(i,2,1),range_collision);
next_motion = gain_agent*agent_influence + gain_obstacle*obstacle_influence + (min_gamma+(max_gamma-min_gamma).*rand(1,1));
new_location(1) = next_motion(1) + flock(i,1,1);
new_location(2) = next_motion(2) + flock(i,1,2);
v1 = [new_location(1)-flock(i,1,1),new_location(2)-flock(i,1,2)];
v2 = [(flock(i,1,1)+cos(deg2rad(flock(i,2,1)))-flock(i,1,1)),(flock(i,1,2)+sin(deg2rad(flock(i,2,1))))-flock(i,1,2)];
d = dot(v1,v2);
nv1 = norm(v1,2);
nv2 = norm(v2,2);
n = nv1*nv2;
if n ~= 0
t = d/n;
new_heading = acos(t);
delta_heading = new_heading;
if new_heading > pi/2
d = -1;
else
d = 1;
end
if delta_heading > max_turn
delta_heading = max_turn;
end
if isreal(delta_heading)
tmp_flock(i,2,1) = mod((flock(i,2,1)+(d*rad2deg(delta_heading))+360),360);
else
tmp_flock(i,2,1) = flock(i,2,1);
end
else
tmp_flock(i,2,1) = flock(i,2,1);
end
if norm(next_motion,2) > max_motion
next_motion = next_motion*(max_motion)/norm(next_motion,2);
elseif norm(next_motion,2) == 0
next_motion = [(flock(i,1,1) + min_motion*cos(deg2rad(flock(i,2,1)))-flock(i,1,1)),
(flock(i,1,2)+min_motion*sin(deg2rad(flock(i,2,1)))-flock(i,1,2))];
end
tmp_flock(i,1,1) = tmp_flock(i,1,1) + next_motion(1);
tmp_flock(i,1,2) = tmp_flock(i,1,2) + next_motion(2);
end
End Code
The above code works but is slow. Below is my attempt to speed things up but the below code is broken in the following ways:
- does not compute the obstacle_influence (do not worry about this part)
- it does not take in account the range_sensing variable
- it does not compute the correct values (namely max_motion)
- am I on the right track for vectorizing this code
Attempt
% --- grab the flock locations
locations = flock(:,1,:);
% --- get the dimension and size of the flock
[flock_size,dims] = size(locations);
% --- reshape the location matrice
a = reshape(locations,1,flock_size,dims);
b = reshape(locations,flock_size,1,dims);
% --- compute the distances
distances = sqrt(sum((a(ones(flock_size,1),:,:) - b(:,ones(flock_size,1),:)).^2,3));
% --- convert the diagonal to NaN'a
distances(logical(eye(size(distances)))) = NaN;
% --- grab the minimum distances
[min_distances,min_index] = min(distances,[],2);
% --- grab the locations of the minimum distances
locations_of_min = locations(min_index,:);
% --- check which distances are within the repulsion radius
repulsion = range_agent_repulsion*ones(flock_size);
t = bsxfun(@ge, min_distances, repulsion);
for i = 1 : flock_size
if t(i)
locations_of_min(i,:) = [0,0];
end
end
% --- reshape locations
locations = reshape(locations,flock_size,2);
% --- compute the agent influence vector
next_motion = locations-locations_of_min;
next_motion = next_motion*gain_agent;
% --- add random noise
next_motion = next_motion + (min_gamma+(max_gamma-min_gamma).*rand(1,1));
% TODO calc the obstacle avoidance
obstacle_influence = [0,1];
obstacle_influence = ones(flock_size,2);
% --- add obstacle_influence to next_motion
next_motion = next_motion + gain_obstacle*obstacle_influence;
% --- set the new desired location for each agent
new_location = next_motion+locations;
% --- compute headings
v1 = new_location-locations;
v2 = [(flock(:,1,1)+cos(deg2rad(flock(:,2,1)))-flock(:,1,1)),(flock(:,1,2)+sin(deg2rad(flock(:,2,1))))-flock(:,1,2)];
% --- compute the agents headings
d = dot(v1,v2,2);
nv1 = sqrt(sum(abs(v1).^2,2));
nv2 = sqrt(sum(abs(v2).^2,2));
normal = bsxfun(@times, nv1, nv2);
for i = 1 : flock_size
if normal(i) ~= 0
t = d(i)/normal(i);
new_heading = acos(t);
delta_heading = new_heading;
if new_heading > pi/2
% --- turn right
direction = -1;
else
% --- turn left
direction = 1;
end
if delta_heading > max_turn
delta_heading = max_turn;
end
if isreal(delta_heading)
flock(i,2,1) = mod((flock(i,2,1)+(direction*rad2deg(delta_heading))+360),360);
else
flock(i,2,1) = flock(i,2,1);
end
else
flock(i,2,1) = flock(i,2,1);
end
end
normal_motion = sqrt(sum(abs(next_motion).^2,2));
in_range = normal_motion > max_motion;
next_motion(in_range) = bsxfun(@rdivide, next_motion(in_range)*max_motion, normal_motion(in_range));
% --- set the new locations of the flock members
locations = bsxfun(@plus, locations, next_motion);
flock(:,1,:) = locations;
4 Comments
Answers (0)
This question is closed.
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!