Set generation algorithm: Matlab - matlab

Consider the code :
clear all
N = 7;
Set = 1:N;
for i = 1:N-1
Set1 = nchoosek(Set,i);
[ L_Set1 , C_Set1] = size(Set1);
A = zeros( L_Set1,N-C_Set1);
ASS_R7 = zeros( L_Set1 , N+1 );
for i1 = 1:L_Set1
A(i1,:) = setdiff( 1:N , Set1(i1,:) );
ASS_R7(i1,:) = [ Set1(i1,:), 0 ,A(i1,:) ];
end
ASS_R(i) = {ASS_R7};
end
Here, ASS_R gives all the possible [ (N-k) 0 k ] sets where the elements are unique (and belong to [1,7].Also k>0).
I have been trying to generalize this code for all N<=7 and have not been able to come up with a solution.
To be more clear:
We get a cell array with cells of different sizes which look like this:
[ 1 2 3 4 5 6 0 7 ] . . . [ 1 0 2 3 4 5 6 7 ]
. .
{ . } . . . { . }
. .
[ 2 3 4 5 6 7 0 1 ] . . . [ 7 0 1 2 3 4 5 6 ]
However, I want all cells
[ 1 0 2 ] [ 1 0 2 3] [ 1 0 2 3 4 5 6 7 ]
. . .
{ . } . . { . } . . . { . }
. . .
[ 7 0 6 ] [ 7 0 6 5] [ 7 0 1 2 3 4 5 6 ]
[ 1 2 0 3 ] [ 1 2 0 3 4 5 6 7 ]
. .
{ . } . . . { . }
. .
[ 6 7 0 5 ] [ 6 7 0 1 2 3 4 5 ]
[ 1 2 3 4 5 6 0 7 ]
.
{ . }
.
[ 2 3 4 5 6 7 0 1 ]
Any ideas, guys?

Code
%%// Array of elements whose sets are to be formed
arr1 = 1:7;
%%// Get a size estimate of the final output cell array and initialize it
lim1 = cumsum(1:numel(arr1)-1);
outmat = cell(lim1(end),1);
%%// Get the cell array of sets, into outmat
cc1=1;
for k3 = 1:numel(arr1)-1
t1 = nchoosek(arr1,k3);
for k2=1:numel(arr1)-k3
mat1 =[];
for k1 = 1:size(t1,1)
t11 = t1(k1,:);
t2 = arr1(~ismember(arr1,t11));
t3 = nchoosek(t2,k2);
t4 = [repmat([t11 0],size(t3,1),1) t3];
mat1= [mat1; t4];
end
outmat(cc1)={mat1}; %%// Output
cc1 = cc1+1;
end
end

Related

How can I shuffle the order of a matrix in NetLogo?

How can I shuffle the contents of a matrix and preserve it as a matrix? The shuffle function works for lists but not for matrices
show shuffle [1 2 3 4 5]
1 2 3 5 4
set m matrix:from-row-list
[[1 2 3 4 5]]
show shuffle m
SHUFFLE expected input to be a list but got the
org.nlogo.extensions.matrix.MatrixExtension$LogoMatrix {{matrix: [ [
1 2 3 4 5 ] ]}} instead.
There may be an easier way, but you could jump to a list, shuffle, then come back to a matrix based on the dimensions of your original matrix.
extensions [ matrix ]
to setup
ca
let m matrix:from-row-list [ [ 1 2 3 ] [ 4 5 6 ] [ 7 8 9 ] ]
let sm shuffled-matrix m
print matrix:pretty-print-text sm
reset-ticks
end
; Reporter returns a shuffled matrix
to-report shuffled-matrix [ mat ]
; Get the number of columns
let cols last matrix:dimensions mat
; Shuffle the matrix values as a list
let shuf-vals shuffle reduce sentence matrix:to-row-list mat
; Use the shuffled values to generate a new matrix
; with the same dimensions as the original
report matrix:from-row-list ( subsetter shuf-vals cols )
end
; Reporter returns a list cut into sublists
; based on the len value passed
to-report subsetter [ ls len ]
; Generate subsetting indices for the sublists
let vals ( range 0 ( length ls ) len )
; Make subsets of ls based on the subsetting indices
report map [ i -> sublist ls i ( i + len ) ] vals
end
A few example outputs from setup:
[[ 1 6 7 ]
[ 9 5 8 ]
[ 3 4 2 ]]
[[ 4 6 8 ]
[ 1 9 2 ]
[ 7 5 3 ]]
[[ 2 9 4 ]
[ 6 3 8 ]
[ 5 1 7 ]]

How to overlap 2 matrices, where zeros are "transparent"

I have 2 matrices, say
A = [ 0 4 9 B = [ 0 0 2
0 2 1 1 6 1
3 0 0 ] 3 9 8 ]
I want the result to be "A overlapped with B".
Any elements of B which are 0 should be "transparent" and show through the value of A
All other elements should be the balue of B.
So I should get:
result = [ 0 4 2
1 6 1
3 9 8 ]
A=[ 0 4 9;
0 2 1;
3 0 0];
B=[ 0 0 2;
1 6 1;
3 9 8];
result = A;
result( B~=0 ) = B( B~=0 );

Perl PDL not working as expected

I really don't understand PDL's input functions. Personally, I've been using the rcols feature to create pdls, as was recommended to me in various places around the web.
I have an input file like this :
3 -4 -1
0 5 2
3 5 6
2 5 2
5 5 5
5 5 6
which, I want to assign to a Piddle. When I assign it to a piddle like so,
my #pdls = rcols $in_fh, { COLSEP => "\\s" } ;
my $pdl = pdl(#pdls[1 .. $#pdls]);
When I print #pdls this is printed :
[
[ 3 0 3 2 5 5]
[-4 5 5 5 5 5]
[-1 2 6 2 5 6]
]
Which made me think it pulled my file by columns, and not rows. Which makes sense looking at the code, really. When I saved this output to a file(After stripping out all the brackets) this is how it looked. :
3 0 3 2 5 5
-4 5 5 5 5 5
-1 2 6 2 5 6
When I ran the same script on the new input file, the result does not follow the same process as before :
[
[ 0 -4 -1]
[ 3 0 0]
[ 0 5 2]
[ 0 0 0]
[ 0 5 6]
[ 3 0 0]
[ 0 5 2]
[ 2 0 0]
[ 0 5 5]
[ 5 0 0]
[ 0 5 6]
[ 5 0 0]
]
And I have no idea why it is doing so. In essence, I want to be able to read my text file into a piddle. Does anyone see what I'm missing, or able to offer any explanation?
Thanks for any help.
As is occasionally the case in PDL, the design of things with several dimensions can be a bit counter-intuitive. But it is designed overall so it's easy to just adjust dimensions. Here, rcols and wcols treat data in files in a FORTRAN-style column-major way. It is easy to adjust that using the transpose method:
pdl> p $x = sequence(3,4)
[
[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]
]
pdl> wcols($x->transpose, 'myfile')
pdl> p pdl(rcols('myfile', {colsep => qr/\s+/}))->transpose
Reading data into ndarrays of type: [ Double Double Double ]
Read in 4 elements.
[
[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]
]
Maybe its just better to make a "3,6 matrix of zeros" then set in each value individually, (which means putting the data from a file into a 1D pdl() first) I would use a open() to read it into a scaler then put that in a 1D piddle; which can be rather involved ... once you get it in a 1D piddle do this:
open(FILE,"yourfile"); while (<FILE>) { $x = $_; }
close FILE;
$y = zeros(3,6);
p $x = sequence(18);
[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17]
for $c(0..5) { for $d(0..2) { $y($d,$c) .= $x($e++) }}
p $y
[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]
[12 13 14]
[15 16 17]

creating a matrix,whose size is similar to a given matrix but all elements are identical

I have a n/n matrix A.
Now I want to create a new matrix B which has same size as A but with all 2.
Example :
If A = [ 1 2 3; 4 5 6; 7 8 9 ], B becomes B = [ 2 2 2; 2 2 2; 2 2 2 ] .

Splitting k - combinations into 2 in a specific manner in Matlab

Consider a set,
S = {1,2,3,4,5,6,7}
I am trying to come up with a function which takes S as the input and gives me ALL possible arrays:
[ 1 ~ 2 ; 1 ~ 3 ; 1 ~ 4 ; 1 ~ 5 ; . . . ; 6 ~ 7 ]
[ 1 2 ~ 3 ; 1 2 ~ 4 ; ...; 2 3 ~ 1 ; 2 3 ~ 4....; 5 6 ~ 7]
.
.
.
[ 2 3 4 5 6 7 ~ 1 ; 1 3 4 5 6 7 ~ 2 ; ... ; 1 2 3 4 5 6 ~ 7 ]
Here notice that '~' is sort of like a delimiter placed in between the elements of k - combination such that the set appearing before the delimiter is always unique in each array.
For example, we want both 7-combinations
[ 2 3 4 5 6 7 ~ 1 ] and [ 1 2 3 4 5 6 ~ 7 ].
But we want only one of
[ 1 2 3 4 5 6 ~ 7 ] and [ 1 3 4 5 6 2 ~ 7 ].
My Code :
clear all
for k = 1:7
Set = nchoosek(1:7,k);
for i = 1:length(Set)
A = setdiff(1:7,Set(i,:));
P = nchoosek( A , 2 ); % trialing it for only A~B where B has only 2elements
L = length( P );
S = repmat( Set ( i,: ) , L,1);
for j = 1:L
S1(j,:) = setdiff( S(j,:) , P(j,:) );
W(j,:) = [ S1(j,:) , 0 , P(j,:) ];
end
W1(i,k) = {W};
end
end
This however produces an error at k=2.
Any ideas to make this work and efficiently.
I think I can outline how to achieve this.
to get the subset (for A) use setdiff
s = 1:7
b = 4
tmp = setdiff(s,b)
for the permutation use randperm
t2 = randperm(length(tmp))
A = tmp(t2)
for the specific subsets just pick the first n entries of A
Put the whole thing in some loops to create the set you describe.