Search code examples
matlabclamp

forcing the columns of a matrix within different limits


I have a matrix named l having size 20X3. What I wanted to do was this : Suppose I have this limits:

l1_max=20; l1_min=0.5;
l2_max=20; l2_min=0.5;
mu_max=20; mu_min=0.5;

I wanted to force all the elements of the matrix l within the limits. The values of 1st column within l1_max & l1_min. The values of 2nd column within l2_max & l2_min. The values of 3rd column within mu_max & mu_min.

What I did was like this:

for k=1:20
    if l(k,1)>l1_max 
        l(k,1) = l1_max;
    elseif l(k,1)<l1_min
        l(k,1) = l1_min;
    end

    if l(k,2)>l2_max 
        l(k,2) = l2_max;
    elseif l(k,2)<l2_min
        l(k,2) = l2_min;
    end

    if l(k,3)>mu_max 
        l(k,3) = mu_max;
    elseif l(k,3)<mu_min
        l(k,3) = mu_min;
    end
end

Can it be done in a better way ?


Solution

  • You don't have to loop over rows, use vectorized operations on entire columns:

    l(l(:, 1) > l1_max, 1) = l1_max;
    l(l(:, 1) < l1_min, 1) = l1_min;
    

    Similarily:

    l(l(:, 2) > l2_max, 2) = l2_max;
    l(l(:, 2) < l2_min, 2) = l2_min;
    l(l(:, 3) > l2_max, 3) = mu_max;
    l(l(:, 3) < l2_min, 3) = mu_min;
    

    An alternative method, which resembles to Bas' idea, is to apply min and max as follows:

    l(:, 1) = max(min(l(:, 1), l1_max), l1_min);
    l(:, 2) = max(min(l(:, 2), l2_max), l2_min);
    l(:, 3) = max(min(l(:, 3), mu_max), mu_min);
    

    It appears that both approaches have comparable performance.