Vectorization conversion issues for matrix computations
Información
La pregunta está cerrada. Vuélvala a abrir para editarla o responderla.
Mostrar comentarios más antiguos
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 comentarios
Mark Whirdy
el 16 de Dic. de 2012
Hi Benjamin, happy to help but could you re-post a self-contained code set with all variables (flock_size,flock) defined as I get these errors everywhere so can't run the code.
Besides this, one quick observation: the "i = 1:flock_size" loop is probably unnecessary as the operation contained within isn't recursive, & so can probably be vectorized.
>> Untitled ??? Undefined function or variable 'flock'.
Error in ==> Untitled at 7
index = calc_nearest_agent(i,flock,flock_size,range_sensing,range_collision);
Benjamin
el 17 de Dic. de 2012
Benjamin
el 17 de Dic. de 2012
Respuestas (0)
La pregunta está cerrada.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!