Creating a diagonal matrix - loops

This is the code I currently have:
forv i = 1/10 {
set obs 10
gen x`i' = (_n-1)*10+`i'
}
How can I make it into a diagonal matrix so that entries are 0 whenever row ad column indexes are not equal?
This is the code I tried but did not work:
forv i=1/10 {
set obs 10
gen x`i' = (_n-1)*10+`i'
foreach j of varlist x1-x10 {
if _n ~= "`i'"
replace `j' = 0
}
}

Your first code block is legal (assuming no more than 10 observations in memory) but doesn't produce any thing close to a diagonal matrix. The command set obs 10 should be executed once before the loop, not every time around the loop.
There are several errors in your inner loop in your second code block, but I won't spell them out. You're guessing wildly, not the way to write code!
You can get a diagonal matrix directly in Stata like this:
. matrix whatever = 7 * I(5)
. matrix list whatever
symmetric whatever[5,5]
c1 c2 c3 c4 c5
r1 7
r2 0 7
r3 0 0 7
r4 0 0 0 7
r5 0 0 0 0 7
If you have reason to hold that as variables, then use svmat. You could create such a matrix as values of several variables in a loop, but it would be somewhat perverse:
clear
set obs 5
forvalues j = 1/5 {
generate x`j' = 7 * (_n == `j')
}
list
+------------------------+
| x1 x2 x3 x4 x5 |
|------------------------|
1. | 7 0 0 0 0 |
2. | 0 7 0 0 0 |
3. | 0 0 7 0 0 |
4. | 0 0 0 7 0 |
5. | 0 0 0 0 7 |
+------------------------+

The solution by #NickCox is also applicable in mata - Stata's matrix programming language:
. mata: A = 7 * I(5)
. mata: A
[symmetric]
1 2 3 4 5
+---------------------+
1 | 7 |
2 | 0 7 |
3 | 0 0 7 |
4 | 0 0 0 7 |
5 | 0 0 0 0 7 |
+---------------------+
One can then get the matrix as variables with the getmata command:
. getmata (A*) = A
. list A*
+------------------------+
| A1 A2 A3 A4 A5 |
|------------------------|
1. | 7 0 0 0 0 |
2. | 0 7 0 0 0 |
3. | 0 0 7 0 0 |
4. | 0 0 0 7 0 |
5. | 0 0 0 0 7 |
+------------------------+

Related

What does CONVERT(INT, N_TYPE)&128 do?

I'm currently working through several SQL Functions someone else did and i am getting results i'm not able to explain.
The broken down part looks like this:
SELECT
N_TYPE,
CONVERT(INT, N_TYPE)&128,
CONVERT(INT, N_TYPE)&64
FROM TBL_EXAMPLE
N_TYPE is a decimal(10,0) field. Some Examples of what i get returned:
+-----------+-------------+------------+
| N_TYPE | CONVERT 128 | CONVERT 64 |
+-----------+-------------+------------+
| 0 | 0 | 0 |
| 200 | 128 | 64 |
| 136 | 128 | 0 |
| 32 | 0 | 0 |
| 536870912 | 0 | 0 |
| 72 | 0 | 64 |
+-----------+-------------+------------+
I thought it returned 64 or 128 respectively, if N_TYPE Is above those values, but this isn't the case (as seen above at N_TYPE=136, where 64 is not returned).
So, what does this actually do?
The first part is converting the N_TYPE column to an int. The second part is using the
& operator which is the a bitwise AND operator.
So if you apply x & 64, you will get a value of 0 if the 7th binary digit from the right is not set, or 64 if that digit is set to 1.
The ampersand (&) in SQL Server is the bit-wise operator for AND, and the way that's used on your example is to determine that the bits that compose the integer values 128 and 64 should also match in position with the bits that compose the value on the left side (the result of CONVERT(INT, N_TYPE)).
Check these examples:
Position 8 7 6 5 4 3 2 1
Result
0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 1
2 0 0 0 0 0 0 1 0
4 0 0 0 0 0 1 0 0
8 0 0 0 0 1 0 0 0
16 0 0 0 1 0 0 0 0
32 0 0 1 0 0 0 0 0
64 0 1 0 0 0 0 0 0
72 0 1 0 0 1 0 0 0
128 1 0 0 0 0 0 0 0
136 1 0 0 0 1 0 0 0
200 1 1 0 0 1 0 0 0
You will see that 200 & 128 will return (bit-wise) 10000000 which are bits that both have 1 (the AND works this way), and that converts back to 128 as INT.
Another example 136 & 8 will return 00001000 which converts back as 8.
In your case & is is a bitwise operator used for bit manipulations between two expressions.
For example
select 200&128
Will be calculated as
200 11001000
& 128 10000000
--------- ---------
= 128 10000000
Similarly
select 31&128
will be calculated as
31 00011111
& 128 10000000
--------- --------
= 0 00000000
You can read more about Bitwise operator Bitwise Operators (Transact-SQL)

Effect of S-gate on one qubit of a combined(maybe entangled) state of 3 qubits

Suppose I have a register(qs) of 3 qubits (first 2 being used solely for control, the last one is the input) . The first two control qubits are in the |+> state and the state of the 3rd input is unknown. Let it be a|0> + b|1>.
Now I apply CCNOT(qs[0],qs[1],qs[2]) so their combined state becomes 0.5(a,b,a,b,a,b,b,a) in Transposed matrix form [Please correct if I'm wrong here] . Now I apply S-gate to the 3rd qubit which transforms |1> -> i|1> .
I am unable to guess the state of the combined state of 'qs' now.
What I thought:
One logic is to multiply every state by 'i' if it has the form|XY1> so the combined state becomes 0.5(a,ib,a,ib,a,ib,b,ia) [Transposed]
Another logic is to find tensor product of (I x I x S) since I'm not changing the first 2 qubits. Performing this yields a different result which is 0.5(a,b,a,b,ia,ib,ib,ia) [Transposed] [Again, correct me if I'm wrong].
Which is the correct output after passing through S-gate (if any) ?
The first two qubits can't start in |+> state, since |+> is a single-qubit state. I assume that the starting state of the first two qubits in the register is 0.5 (|00> + |01> + |10> + |11>).
Both approaches are correct, because they are different ways to represent the same transformation. The first answer 0.5(a,ib,a,ib,a,ib,b,ia) [Transposed] is correct. Your second answer 0.5(a,b,a,b,ia,ib,ib,ia) [Transposed] seems to be obtained by multiplying by S x I x I, i.e., applying S gate on the first qubit instead of the third one.
The tensor product I x I x S can be calculated as tensor product of I x I (which is just a 4x4 identity matrix) and S. The result is an 8x8 matrix which consists of 16 copies of S matrix, multiplied by corresponding elements of I x I:
1 0 | 0 0 | 0 0 | 0 0
0 i | 0 0 | 0 0 | 0 0
- - - - - - - -
0 0 | 1 0 | 0 0 | 0 0
0 0 | 0 i | 0 0 | 0 0
- - - - - - - -
0 0 | 0 0 | 1 0 | 0 0
0 0 | 0 0 | 0 i | 0 0
- - - - - - - -
0 0 | 0 0 | 0 0 | 1 0
0 0 | 0 0 | 0 0 | 0 i
If you multiply the state of the qubits by this matrix, you'll get the same answer as in the first approach.

Create a "pyramid" matrix

Say I'm given a symmetric row vector with an odd length where each element is smaller than the next one in the first half of the vector and each element is bigger than the next one in the second half and the middle element is the biggest. (e.g [1 2 3 2 1] or [10 20 50 20 10]).
I want to create a square matrix where this row vector is its middle row and the equivalent column vector (v') is its middle column and each other row or column is a reduced version of the given vector according to the middle element in this row or column. And when there are no more "original elements" we put 0.
Examples:
if v = [1 2 3 2 1] we get
0 0 1 0 0
0 1 2 1 0
1 2 3 2 1
0 1 2 1 0
0 0 1 0 0
if v = [3 5 3] we get
0 3 0
3 5 3
0 3 0
What I did so far: I managed to create a matrix with v as the middle row and v' as the middle column with this code I wrote:
s = length(vector);
matrix= zeros(s);
matrix(round(s/2),:) = vector;
matrix(:, round(s/2)) = vector';
but got stuck with assigning the other values.
A more hands-on approach is to produce your matrix as a mosaic, starting from a hankel matrix. For performance comparison, here's a version using the same format as #Divakar's solution:
function out=pyramid_hankel(v)
%I suggest checking v here
%it should be odd in length and a palindrome
i0=ceil(length(v)/2);
v2=v(i0:end);
Mtmp=hankel(v2);
out=zeros(length(v));
out(i0:end,i0:end)=Mtmp;
out(1:i0-1,i0:end)=flipud(Mtmp(2:end,:));
out(:,1:i0-1)=fliplr(out(:,i0+1:end));
>> pyramid_hankel([1 2 3 2 1])
ans =
0 0 1 0 0
0 1 2 1 0
1 2 3 2 1
0 1 2 1 0
0 0 1 0 0
For v=[1 2 3 2 1] the starting block is hankel([3 2 1]), which is
ans =
3 2 1
2 1 0
1 0 0
From here it should be clear what's happening.
Here's one approach -
function out = pyramid(v)
hlen = (numel(v)+1)/2;
updown_vec = [1:(numel(v)+1)/2 (numel(v)-1)/2:-1:1];
upper_part = cumsum(bsxfun(#le,(hlen:-1:1)',updown_vec)); %//'
out = [upper_part ; flipud(upper_part(1:end-1,:))];
out = changem(out,v,updown_vec);
Here's another approach, sort of simpler maybe -
function out = pyramid_v2(v)
hlen = (numel(v)+1)/2;
updown_vec = [1:(numel(v)+1)/2 (numel(v)-1)/2:-1:1];
mask = bsxfun(#le,([hlen:-1:1 2:hlen])',updown_vec); %//'
M = double(mask);
M(hlen+1:end,:) = -1;
out = changem(cumsum(M).*mask,v,updown_vec);
Sample runs -
>> v = [1 2 3 2 1];
>> pyramid(v)
ans =
0 0 1 0 0
0 1 2 1 0
1 2 3 2 1
0 1 2 1 0
0 0 1 0 0
>> v = [3 5 3];
>> pyramid(v)
ans =
0 3 0
3 5 3
0 3 0
>> v = [99,3,78,55,78,3,99];
>> pyramid(v)
ans =
0 0 0 99 0 0 0
0 0 99 3 99 0 0
0 99 3 78 3 99 0
99 3 78 55 78 3 99
0 99 3 78 3 99 0
0 0 99 3 99 0 0
0 0 0 99 0 0 0
Here's another approach:
v = [1 2 3 2 1]; %// symmetric, odd size
m = (numel(v)-1)/2;
w = [0 v(1:m+1)];
t = abs(-m:m);
result = w(max(m+2-bsxfun(#plus, t, t.'),1));

Merge two arrays Matlab

I want to know the shortest route to do this, thus asking the question, though it can be done in many ways.
Suppose there are two arrays
A1 = [x1 y1
x2 y2
x3 y3
0 0
0 0
0 0
0 0
]
and
A2 = [a1 b1
a2 b2
a3 b3
a4 b4
0 0
0 0
0 0
]
Now, how to merge A1 and A2 in the shortest way, such that
A = [x1 y1
x2 y2
x3 y3
a1 b1
a2 b2
a3 b3
a4 b4]
Am weak when it comes to array indexing. I have implemented two for loops and some if statements to do this, but I feel there is a shortest way. Can you please help?
This will remove any rows with all zeros, and put A1 on top of A2. This works because max does column-wise maxima
A=[A1(max(A1')>0,:);A2(max(A2')>0,:)]
You can try this too, if you'd like
A1( all(~A1,2), : ) = []
A2( all(~A2,2), : ) = []
A3=[A1;A2]
The first two statements remove all your zero-filled rows.
The third statement creates your merged array.
For instance, here's an example.
A1=[1,2;3,4;1,5;0,0;0,0]
A2=[7,1;6,1;0,0;0,0;0,0;0,0]
A1( all(~A1,2), : ) = []
A2( all(~A2,2), : ) = []
A3=[A1;A2]
And here's the output
Before removing zeroes
A1 =
1 2
3 4
1 5
0 0
0 0
A2 =
7 1
6 1
0 0
0 0
0 0
0 0
After removing zeroes
A1 =
1 2
3 4
1 5
A2 =
7 1
6 1
Merged :
A3 =
1 2
3 4
1 5
7 1
6 1
This should probably do your job. If
A1 =
1 2
3 4
5 6
0 0
0 0
0 0
0 0
and
A2 =
7 8
9 10
11 12
13 14
0 0
0 0
0 0
then
[[nonzeros(A1(:,1)),nonzeros(A1(:,2))];[nonzeros(A2(:,1)),nonzeros(A2(:,2))]] returns
ans =
1 2
3 4
5 6
7 8
9 10
11 12
13 14
Hope it helps.
Edit | Note: This solution will not work if A1/A2 has rows of the type [0 x] or [x 0].
Try this:
A = A1;
A(A == 0) = A2(A2 ~= 0);
I think this one belongs here too:
A = reshape(nonzeros([A1; A2]),[],2)

linked representation of sparse matrices

for sparse matrices i had put a question about its linked representation.
there were two lists to be implemented for a nine zero elements of a 5x8 matrix.....one is the coloumn list and another one is the row list.....
now here is a problem both the lists have properties as follows:
1) row list:- row,col,data,right
2) coloumn list:-row,col,data,down
the link is through either the down or right field
i have created a sparse matrice as follows:
_1_2_3_4_5_6_7_8_
1| 1 0 0 0 0 6 0 9
2| 0 2 0 0 0 0 7 0
3| 0 0 3 0 0 0 0 8
4| 0 0 0 4 0 0 0 0
5| 0 0 0 0 5 0 0 0
i googled around and finally got some representation in ibm site
but the real headache for me is i am just not getting enough help how to represent the elements as in both the list.
should both the list contain all 9 non zero elements?
can anybody suggest something?
the link list representation of the matrix is
|5|9|9| |-> |1|1|1| | -> |1|6|6| | -> |1|8|9| | -> |2|2|2| |->|2|7|7| |-> |3|3|3| |->|3|8|8| |->|4|4|4| |->|5|5|5|null|
here first node show the total number of row and columns.the 2nd ,3rd and so on shows the the values of row, column ,nonzero values of the corresponding values.
1| 1 0 0 0 0 6 0 9
2| 0 2 0 0 0 0 7 0
3| 0 0 3 0 0 0 0 8
4| 0 0 0 4 0 0 0 0
5| 0 0 0 0 5 0 0 0

Resources