Is it possible to vectorize/optimize boundary dependent variable addition in for loop?

Hi
I made a code that i got vectorized until a certain for loop. In the loop indices of a vector has to be added with itself within boundary indices and a calculated solution. I created a simple example to visualize the problem. (Matlab v. 9.1.0.441655 (R2016b))
clc
clearvars
close all
% Boundaries are calculated at forehand
boundary1 = linspace(1,10000,10000);
boundary2 = linspace(10000,19999,10000);
numberOfPoints = boundary2(end);
numberOfBoundaries = length(boundary2);
% The solution matrix has to be added to specific places in the solution.
% They overlap each other
calculatedMatrix = ones(numberOfBoundaries,numberOfPoints);
% The solution vector is initialized
solutionVector = zeros(1,numberOfPoints);
% A grid of the data
gridVec = 1:1:19999;
% The for loop has to run as long as there is values in the boundary
% vectors. Is it possible to optimize this
tic
for i = 1:numberOfBoundaries
% The boundary vectors are connected this way
indices = boundary1(i):boundary2(i);
% And the solution vectors has to be added up like this with the
% calculated data.
solutionVector(indices) = solutionVector(indices) + calculatedMatrix(i,indices);
end
timeLoop = toc;
% Plotting the summation to visualize the solution
figure(1)
plot(gridVec,solutionVector,'r','linewidth',2);
grid on
xlabel('Grid value')
ylabel('Addiation Value')
Do anyone have a smart trick to speed up the for loop?
Thanks at forehand
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% EDIT
An update to the simplified problem to unsimplify abit. The grid could be e.g. 10000 elements with over 1e6 matrix centerpoints to calculate points at. I still keep the calculated matrix as a simplified ones matrix as the real calculation will unnecessarily overcomplicate the loop compared to the issue
clc
clearvars
close all
% Setting the grid and centerpoints of the calculation matrix
gridVec = 1:0.1:1e4;
calculationMatrixCenterPointsOnGrid = 1:0.01:1e4;
% Setting the number of points in the grid
numberOfPoints = length(gridVec);
% Boundaries are calculated at forehand
lower = calculationMatrixCenterPointsOnGrid-30;
upper = calculationMatrixCenterPointsOnGrid+30;
% Setting the gradient of the grid
gradientGrid = gridVec(2)-gridVec(1);
% Calculating the boundaries based on the center points
boundaryLower = ceil(lower/(gradientGrid(1)) - ...
min(gridVec)/gradientGrid(1));
boundaryUpper = ceil(upper/(gradientGrid(1)) - ...
min(gridVec)/gradientGrid(1));
% Checking for grid bounds
boundaryLower(boundaryLower<=0) = 1;
boundaryUpper(boundaryUpper>numberOfPoints) = numberOfPoints;
% Setting the number of boundaries
numberOfBoundaries = length(boundaryUpper);
% The solution vector is initialized
solutionVector = zeros(1,numberOfPoints);
% The for loop has to run as long as there is values in the boundary
% vectors. Is it possible to optimize this
tic
for i = 1:numberOfBoundaries
% The boundary vectors are connected this way
indecies = boundaryLower(i):boundaryUpper(i);
% The grid that the resulat has to span over (really an input to the
calculationMatrix)
calculationGrid = gridVec(indecies);
% The solution matrix has to be added to specific places in the solution.
% They overlap each other
calculatedMatrix = ones(1,length(indecies));
% And the solution vectors has to be added up like this with the
% calculated data.
solutionVector(indecies) = solutionVector(indecies) + calculatedMatrix;
end
timeLoop = toc;
% Plotting the summation to visualize the solution
figure(1)
plot(gridVec,solutionVector,'r','linewidth',2);
grid on
xlabel('Grid value')
ylabel('Addiation Value')

1 Comment

I think it's too simple an example to know best how to optimize it. Are boundary1 and boundary2 always sequential numbers?

Sign in to comment.

 Accepted Answer

e=1:numberOfPoints;
mask=(boundary1.'<=e) & (e<=boundary2.'); %implicit expansion in R2016b
solutionVector=sum(calculatedMatrix.*mask,1);

1 Comment

At first, thank you for using time on this. I have upgraded the question with an upgraded example that might be more representative
OBS! I will update the new code example again to have more elements

Sign in to comment.

More Answers (2)

If boundary1 and boundary2 are sequential, as in the example,
mask = ones(numberOfBoundaries,numberOfPoints);
mask=triu(tril(mask,numberOfBoundaries-1));
solutionVector=sum(calculatedMatrix.*mask,1);
In your revised example, calculatedMatrix is now being computed on the fly inside the for-loop. I would bet that that is the most significant bottleneck of the loop. Vectorization is therefore unlikely to be of any benefit unless that particular calculation is something that can be vectorized. Your best bet is probably PARFOR.

1 Comment

Actually, it is partly vectorized I was hoping for, as to save memory there need to be some kind of for loop. That is why I made the simplest example as that was the only part I did not know how to deal with. I only upgraded the code as you asked for it.
My plan is to set a constraint so there is allocated 500 MB of matrix that deal with the "vectorization" and reduce the for loop based on the number of "loop iterations" that can be included in the matrix. This is only a small part of several thousand lines of code for a program that I made some time ago. I just needed to speed up the only loop that is in the code as it is the bottleneck when there has to be calculated 1.5e8 lines of data.
The first answer you gave might help me do that. Therefore I will accept that answer. Thank you for the help.

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products

Asked:

on 16 Oct 2017

Commented:

on 17 Oct 2017

Community Treasure Hunt

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

Start Hunting!