Assigning a single value to cell array with logical indexing.

on 10 May 2013

per isakson (view profile)

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'

Products

No products are associated with this question.

per isakson (view profile)

on 11 May 2013
Edited by per isakson

per isakson (view profile)

on 11 May 2013

"... 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.

[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

John

John (view profile)

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

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