Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Assigning a single value to cell array with logical indexing.

Asked by John on 10 May 2013

Hi All,

I am wondering if the code I have below is optimal for what it does, or if there are better ways to do this.

VDIV{1} = [2 5 7 10 13 13.2 20 30 50 100 200 500 1000]*1E-3;
VDIV{2} = [VDIV{1} 5 10];
numVDIVs = numel(VDIV{2});
AmpLimitField = cell(numVDIVs,1);
[AmpLimitField{VDIV{2} < 102E-3}] = deal('X1');
[AmpLimitField{VDIV{2} >= 1.02}] = deal('X100');
% When VDIV{2} >= 102E-3 && VDIV{2} < 1.02}
  [AmpLimitField{cellfun(@isempty,AmpLimitField)}] = deal('X10');

Outputs:

AmpLimitField = 
      'X1'
      'X1'
      'X1'
      'X1'
      'X1'
      'X1'
      'X1'
      'X1'
      'X1'
      'X1'
      'X10'
      'X10'
      'X10'
      'X100'
      'X100'

0 Comments

John

Tags

Products

No products are associated with this question.

1 Answer

Answer by per isakson on 11 May 2013
Edited by per isakson on 11 May 2013
Accepted answer

"... for what it does ..."

  • it creates a cell array of strings, AmpLimitField
  • it takes a cell array, VDIV, as input

However, I see no reason why not use an array of double in place of VDIV. Thus, I have replaced VDIV{2} by vdv.

Your assignment

    [AmpLimitField{cellfun(@isempty,AmpLimitField)}] = deal('X10');

is questionable, since it may hide mistakes in the logic. Whether or not all the greater and lesser than are correct a string will be assigned to AmpLimitField. It is better that a mistake show up as an empty cell.

One more comment

    CellArray( condition ) = { string };

is easier to read and a bit faster than

    [ CellArray{ condition } ] = deal( string );

.

Try

    >> cssm
    Elapsed time is 0.000082 seconds.
    Elapsed time is 0.000228 seconds.
    Equal!
    >> 

where

    function    cssm()
        tic
        alf1 = cssm_();
        toc
        tic
        alf2 = op();
        toc
        if all( cellfun( @(s1,s2) all(eq(s1,s2)), alf1, alf2 ) )
            disp( 'Equal!' )
        else
            disp( 'Not equal!' )
        end
    end
    function    alf = cssm_()
        vdv = [ [2,5,7,10,13,13.2,20,30,50,100,200,500,1000]*1E-3, 5, 10 ];
        len = numel( vdv );
        alf = cell( len, 1 );
        alf(                vdv < 0.102 ) = {'X1'};
        alf( vdv >= 0.102 & vdv < 1.02  ) = {'X10'};
        alf( vdv >= 1.02                ) = {'X100'};
    end
    function    AmpLimitField = op()
        VDIV{1} = [2 5 7 10 13 13.2 20 30 50 100 200 500 1000]*1E-3;
        VDIV{2} = [VDIV{1} 5 10];
        numVDIVs = numel(VDIV{2});
        AmpLimitField = cell(numVDIVs,1);
        [AmpLimitField{VDIV{2} < 102E-3}] = deal('X1');
        [AmpLimitField{VDIV{2} >= 1.02}] = deal('X100');
        % When VDIV{2} >= 102E-3 && VDIV{2} < 1.02}
        [AmpLimitField{cellfun(@isempty,AmpLimitField)}] = deal('X10');
    end

1 Comment

John on 13 May 2013

Thank you very much, per!

I am always looking to learn how to improve my matlab code. On a side note, the reason why VDIV is a cell array is because I am using it in a for loop where in the outer loop, I am iterating on the cell array. I excluded this code from my question to simplify things. The loops are required because I am controlling external instruments and the code must run sequentially through each VDIV element.

VDIV{1} = [2 5 7 10 13 13.2 20 30 50 100 200 500 1000]*1E-3;
VDIV{2} = [VDIV{1} 5 10];
...
for i = 1:2
   ...
   for x = VDIV{i}
      ...
   end
end
per isakson

Contact us