Matlab if loop function, How to improve this function? -
i new matlab , trying figure how write following function in smart/efficient way.
first create matrix y
entries hl
, , every line permutation of predefined length n
.
for example, n=3
first line of matrix y : h h h
. want each line, create matrix of size n x n
example entry (1,2)
corresponds variable links entry y(1,1)
y(1,2)
, , entry y(3,2)
corresponds variable links entry y(1,3)
y(1,2)
. possible?
function a1=mystupidfunction(s , n) %n number of agents , s number of state, function %returns matrix of influence. stupid code must improved work %n agents x = 'hl'; %// set of possible types k = n; %// length of each permutation %// create possible permutations (with repetition) of letters stored in x c = cell(k, 1); %// preallocate cell array [c{:}] = ndgrid(x); y = cellfun(@(x){x(:)}, c); y = [y{:}]; a1 = sym('a1',[n n], 'positive' ); syms h l a_hh a_hl a_lh a_ll k=s i=1:n j=1:n if ( y(k,1)==h) && ( y(k,2)==h) && (y(k,3)==h) a1(i,j)=a_hh elseif ( y(k,1)==l) && ( y(k,2)==l) && (y(k,3)==l) a1(i,j)=a_ll elseif ( y(k,1)==h) && ( y(k,2)==l) && (y(k,3)==l) a1(1,1)=a_hh a1(1,2)=a_hl a1(1,3)=a_hl a1(2,1)=a_lh a1(3,1)=a_lh a1(2,2)=a_ll a1(2,3)=a_ll a1(3,3)=a_ll a1(3,2)=a_ll elseif ( y(k,1)==h) && ( y(k,2)==h) && (y(k,3)==l) a1(1,1)=a_hh a1(1,2)=a_hh a1(1,3)=a_hl a1(2,1)=a_hh a1(3,1)=a_lh a1(2,2)=a_hh a1(2,3)=a_hl a1(3,3)=a_ll a1(3,2)=a_lh elseif ( y(k,1)==l) && ( y(k,2)==l) && (y(k,3)==h) a1(1,1)=a_ll a1(1,2)=a_ll a1(1,3)=a_lh a1(2,1)=a_ll a1(3,1)=a_lh a1(2,2)=a_ll a1(2,3)=a_lh a1(3,3)=a_hh a1(3,2)=a_hl elseif ( y(k,1)==l) && ( y(k,2)==h) && (y(k,3)==h) a1(1,1)=a_ll a1(1,2)=a_lh a1(1,3)=a_lh a1(2,1)=a_hl a1(3,1)=a_hl a1(2,2)=a_hh a1(2,3)=a_hh a1(3,3)=a_hh a1(3,2)=a_hh elseif ( y(k,1)==l) && ( y(k,2)==h) && (y(k,3)==l) a1(1,1)=a_ll a1(1,2)=a_lh a1(1,3)=a_ll a1(2,1)=a_hl a1(3,1)=a_ll a1(2,2)=a_hh a1(2,3)=a_hl a1(3,3)=a_ll a1(3,2)=a_lh elseif ( y(k,1)==h) && ( y(k,2)==l) && (y(k,3)==h) a1(1,1)=a_hh a1(1,2)=a_hl a1(1,3)=a_hh a1(2,1)=a_lh a1(3,1)=a_hh a1(2,2)=a_ll a1(2,3)=a_hl a1(3,3)=a_hh a1(3,2)=a_hl else a(i,j)=0 end end end end
for example when n=3
, s=1
, function returns:
a = [ a_hh, a_hh, a_hh] [ a_hh, a_hh, a_hh] [ a_hh, a_hh, a_hh]
notes:
c = cell(k, 1); %// preallocate cell array [c{:}] = ndgrid(x); %// create k grids of values y = cellfun(@(x){x(:)}, c); %// convert grids column vectors y = [y{:}];
the output n=3 : y =
hhh lhh hlh llh hhl lhl hll lll
s scalar indicates number of line in matrix y (which corresponds "state")
if have 2 states h
, l
, said in comment use 0
, 1
, binary logic.
to y
combinations, count in binary until have right number of digit , convert each bit state decide:
so order n=3
have:
n = 3 ; = de2bi( (0:2^n-1).' )
which gives 3 digits binary combinations:
a = 0 0 0 1 0 0 0 1 0 1 1 0 0 0 1 1 0 1 0 1 1 1 1 1
if want them in ascii format, can convert them:
b = char( ones(size(a))* 'l') ; b(~a) = 'h' ;
to obtain:
b = hhh lhh hlh llh hhl lhl hll lll
so if want keep "ascii" character logic (and output), job:
function out = combiadjacent( k , n ) yb = de2bi( (0:2^n-1).' ) ; %'// combinations y = char( ones(size(yb))* 'l') ; y(~yb) = 'h' ; = char( zeros(n,2*n) ) ; col=1:n acol = [col col+1] + (col-1) ; a(:,acol) = [y(k,col)*ones(n,1) y(k,:).'] ; end out = reshape( cellstr( reshape(a.',2,[]).' ) , n , n ).' ;
will give cell array output like:
>> = combiadjacent( 4 , 3 ) = 'll' 'll' 'hl' 'll' 'll' 'hl' 'lh' 'lh' 'hh'
however, if not picky exact output format, solution below run faster:
function out = combiadjacent( k , n ) y = de2bi( (0:2^n-1).' ) ; %'// combinations b = ones(n,1)*y(k,:) ; %// use cell array of characters out = cellfun( @(a,b) char(cat(2,a+65,b+65)) , num2cell(b) ,num2cell(b.'),'uni',0) ; %'// or use cell array of double in output (even faster) %// out = cellfun( @(a,b) cat(2,a,b) , num2cell(b) ,num2cell(b.'),'uni',0) %// or cell array of boolean %// out = cellfun( @(a,b) logical(cat(2,a,b)) , num2cell(b) ,num2cell(b.'),'uni',0) ;
which give you
>> = combiadjacent( 4 , 3 ) = 'bb' 'bb' 'ab' 'bb' 'bb' 'ab' 'ba' 'ba' 'aa'
note: whatever solution choose, prudent add checking condition k
make sure user not request line doesn't exist.
Comments
Post a Comment