Use loop to create interactions in SPSS - loops

The below loop fails to correctly create any interaction terms (i.e. new variables that are multiplications of eachother). I am not exactly sure how to correctly specify x(#j + #i), so maybe this is what is messing things up.
DATA LIST LIST / A1L1 A1L2 A1L3 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10.
BEGIN DATA
1 0 0 1 0 0 0 0 0 0 0 0 0
1 0 0 0 1 0 0 0 0 0 0 0 0
0 1 0 0 0 1 0 0 0 0 0 0 0
0 1 0 0 0 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 1 0 0 0 0 0
0 0 1 0 0 0 0 0 1 0 0 0 0
-1 -1 -1 0 0 0 0 0 0 1 0 0 0
-1 -1 -1 0 0 0 0 0 0 0 1 0 0
-1 -1 -1 0 0 0 0 0 0 0 0 0 1
END DATA.
LIST.
vector A1L1P A1L2P A1L3P (10).
vector x = A1L1P1 to A1L3P10.
VECTOR ASC = P1 to P10.
VECTOR EcLvl = A1L1 to A1L3.
LOOP #j = 1 to 3.
LOOP #i = 1 to 10.
COMPUTE x(#j + #i) = (ASC(#i) * EcLvl(#j)).
END LOOP.
END LOOP.
EXECUTE.

Instead of
COMPUTE x(#j + #i) = (ASC(#i) * EcLvl(#j)).
I think you want
COMPUTE x(10*(#j-1) + #i) = (ASC(#i) * EcLvl(#j)).

Related

find all 256 cases of 2 numbers in array of 8 length [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
How can I find all combination of 2 numbers {0,1} in array of 8 length in c,
example
arr[]={0,0,0,0,0,0,0,0}
arr[]={0,0,0,0,0,0,0,1}
arr[]={0,0,0,1,1,0,0,1}
an so on
You can generate all combinations fairly easily using a recursive procedure:
arr = [0,0,0,0,0,0,0,0]
Generate(position)
if position > 8 then
print arr
else
arr[position] = 0
Generate(position+1)
arr[position] = 1
Generate(position+1)
Generate(1)
This will go down 8 levels in the call stack and then print the array [0, 0, 0, 0, 0, 0, 0, 0]. Then it will return to the 7th level, and go down again, printing [0, 0, 0, 0, 0, 0, 0, 1]. It will repeat this process, toggling each of the higher-order bits in turn until all 256 possibilities are generated. Instead of printing the arrays, you could save the arrays as you go.
Another possibility is to just create the 256 8-bit arrays and use an iterative procedure to toggle the elements in such a way as to guarantee you cover all your bases. An example with 4-bit strings:
0 0 0 0 0 0 0 0
0 0 0 0 => toggle bits in 4th position => 0 0 0 1
0 0 0 0 in blocks of size 1 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0
0 0 0 1 => toggle bits in 3rd position => 0 0 0 1
0 0 0 0 in blocks of size 2 0 0 1 0
0 0 0 1 0 0 1 1
0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 1
0 0 0 0 0 0 1 0
0 0 0 1 0 0 1 1
0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 1
0 0 0 0 0 0 1 0
0 0 0 1 0 0 1 1
0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 1
0 0 0 0 0 0 1 0
0 0 0 1 0 0 1 1
0 0 0 0 0 0 0 0
0 0 0 1 => toggle bits in 2nd position => 0 0 0 1
0 0 1 0 in blocks of size 4 0 0 1 0
0 0 1 1 0 0 1 1
0 0 0 0 0 1 0 0
0 0 0 1 0 1 0 1
0 0 1 0 0 1 1 0
0 0 1 1 0 1 1 1
0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 1
0 0 1 0 0 0 1 0
0 0 1 1 0 0 1 1
0 0 0 0 0 1 0 0
0 0 0 1 0 1 0 1
0 0 1 0 0 1 1 0
0 0 1 1 0 1 1 1
0 0 0 0 0 0 0 0
0 0 0 1 => toggle bits in 1st position => 0 0 0 1
0 0 1 0 in blocks of size 8 0 0 1 0
0 0 1 1 0 0 1 1
0 1 0 0 0 1 0 0
0 1 0 1 0 1 0 1
0 1 1 0 0 1 1 0
0 1 1 1 0 1 1 1
0 0 0 0 1 0 0 0
0 0 0 1 1 0 0 1
0 0 1 0 1 0 1 0
0 0 1 1 1 0 1 1
0 1 0 0 1 1 0 0
0 1 0 1 1 1 0 1
0 1 1 0 1 1 1 0
0 1 1 1 1 1 1 1

Making two matrix from one

I have a matrix that I would like to split into two separate matrices based on a set of conditions.
The input matrix can be generated with the following code:
lbits = 8;
ntags = 10;
k = randi(lbits,1,ntags);
Tag = zeros(lbits,ntags);
Tag(lbits*(find(k)-1) + k)=1;
TagAnswer = Tag';
Which returns:
TagAnswer =
0 0 0 1 0 0 0 0
0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 0
My conditions are:
If place of bit '1' is on position lbits/2 or higher, add the row to matrix A
If place of bit '1' is less then position lbits/2, add the row to matrix B
With the above TagAnswer I want the 2nd, 5th and 7th rows to be moved into B and the remaining rows moved into matrix A
Assuming my edit is correct, you can use the row and column outputs of find to index TagAnswer and pull the rows based on your conditions:
% Generate sample data
lbits = 8;
ntags = 10;
k = randi(lbits,1,ntags);
Tag = zeros(lbits,ntags);
Tag(lbits*(find(k)-1) + k)= 1;
TagAnswer = Tag';
% Find bit locations and distribute rows accordingly
[r, c] = find(TagAnswer);
A = TagAnswer(r(c>=(lbits/2)), :);
B = TagAnswer(r(c<(lbits/2)), :);
For my test case I have:
TagAnswer =
0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 0
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0
A =
0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1
B =
0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 1 0 0 0 0 0
Edit: Because MATLAB stores data column-major, find also works column-major and will likely lose the row ordering. If it important to preserve the row ordering of TagAnswer in A and B you can use sort after the find call:
[r, sortidx] = sort(r);
c = c(sortidx);

how to create this matrix without using for loop?

I want to create a N*N matrix A.
when n = 4
2 0 -2 0
2 0 2 0
0 2 0 -2
0 2 0 2
when n = 8
2 0 0 0 -2 0 0 0
2 0 0 0 2 0 0 0
0 2 0 0 0 -2 0 0
0 2 0 0 0 2 0 0
0 0 2 0 0 0 -2 0
0 0 2 0 0 0 2 0
0 0 0 2 0 0 0 -2
0 0 0 2 0 0 0 2
I can create this using nested for loop, but how to achieve it more efficiently? Are there any methods without for loop?
Thanks
Here's one way with bsxfun -
A = zeros(n);
idx = bsxfun(#plus,[0:(n/2)-1]*((n+3)-1),[1:2].');
A(idx) = 2;
A(idx+numel(A)/2) = -2;
Sample runs -
Case #1 :
>> n = 4;
>> A
A =
2 0 -2 0
2 0 -2 0
0 2 0 -2
0 2 0 -2
Case #2 :
>> n = 8;
>> A
A =
2 0 0 0 -2 0 0 0
2 0 0 0 -2 0 0 0
0 2 0 0 0 -2 0 0
0 2 0 0 0 -2 0 0
0 0 2 0 0 0 -2 0
0 0 2 0 0 0 -2 0
0 0 0 2 0 0 0 -2
0 0 0 2 0 0 0 -2
You can do it like that:
[reshape([repmat([ 2;2;zeros(n,1)],n/2-1,1); 2;2],n,n/2) ...
reshape([repmat([-2;2;zeros(n,1)],n/2-1,1);-2;2],n,n/2) ]
This only will work, if n is a power of two, obviously.
[EDIT]
It might be faster to use
[reshape([repmat([ 2;2;zeros(n,1)],n/2-1,1); 2;2; ...
repmat([-2;2;zeros(n,1)],n/2-1,1);-2;2] ,n,n) ]
[EDIT2]
This is only a good idea, if you have n of moderate size. If you need really big matrices, you should use sparse matrices. In this case a loop is what you want.

Check all diags in square matrix for true

I am trying to check if in a square matrix there is more than one true value in all possible diagonals and anti-diagonals, and return true, otherwise false.
So far I have tried as following but is not covering all possible diagonals:
n=8; %matrix dimension 8 x 8
diag= sum(A(1:n+1:end));
d1=diag>=2;
antiDiag=sum(A(n:n-1:end));
d2=antiDiag>=2;
if ~any(d1(:)) || ~any(d2(:))
res= true;
else
res=false;
end
this is a false:
0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
this is a true:
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
Since these are my first steps in using Matlab, is there a specific function or a better way to achieve the result I am looking for?
To detect if there are more than one nonzero value in any diagonal or anti-diagonal (not just the main diagonal and antidiagonal): get the row and column indices of nonzero values, ii and jj; and then check if any value of ii-jj (diagonals) or ii+jj (anti-diagonals) is repeated:
[ii, jj] = find(A);
res = (numel(unique(ii-jj)) < numel(ii)) || (numel(unique(ii+jj)) < numel(ii));
One approach:
n=8; %// size of square matrix
A = logical(randi(2,n)-1); %// Create a logical matrix of 0s and 1s
d1 = sum(A(1:n+1:end)); %// sum all the values of Main diagonal
d2 = sum(A(n:n-1:end-1)); %// sum all the values of Main anti-diag
result = d1>=2 | d2>=2 %// result is true when any one of them is > than or = to 2
Sample run:
Inputs:
>> A
A =
0 1 1 1 1 0 1 0
0 1 1 1 1 1 0 0
0 1 0 1 1 0 0 1
0 1 1 0 1 1 0 0
0 1 0 1 1 0 0 1
1 0 0 0 1 1 0 1
1 1 1 1 1 1 0 0
1 1 1 1 0 0 0 1
Output:
result =
1
Note: This approach considers only the Main diag and Main Anti-Diag (considering the example you provided). If you want for all possible diags, the other answer from Luis Mendo is the way to go
Using #Santhan Salai's generating technique, we can use the diag function (to pull out the main diagonal of the matrix), the fliplr to flip over the center column and any to reduced to a single value.
n=8; %// size of square matrix
A = logical(randi(2,n)-1); %// Create a logical matrix of 0s and 1s
any([diag(A) ; diag(fliplr(A))])

Adjacency matrix of binary tree of depth 4 in C

How would the adjacency matrix of binary tree of depth 4 in C look like? The depth of a node is defined as its distance from the root.
I know a is at depth zero e is at depth 2
a
/ \
b c
/ \ / \
d e f g
/ \ / \ / \ / \
h i j k l m n o
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
a b c d e f g h i j k l m n o
a 1 1 0 0 0 0 0 0 0 0 0 0 0 0
b 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0
c 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0
d 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0
e 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0
f 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0
g 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1
h 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
i 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
j 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
k 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
l 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
m 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
n 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
o 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
Just an observation. Holds true in general.
If you have a complete binary tree, by which I mean all internal nodes have two children, and all leaves at same depth. And if you number them starting from 1
i.e. in your case
a = 1; b = 2; c = 3 ....
For any node x -> i
It's children will be 2*i and 2*i + 1
And it's parent will be floor(i/2)
In your case, you can just hard-code it since you have only depth = 4

Resources