Randomly generate signed permutation matrix in Julia? - matrix

In Julia, I would like to generate a matrix with exactly one nonzero entry in each row and column, where each of these nonzero entries has modulus one. Is there any way to this in Julia?

The result matrix has only n nonzero entries, so it is going to be sparse. So it might as well be generated as a sparse matrix:
using SparseArrays, Random
randspermmat(n) = SparseMatrixCSC(n, n,
collect(1:n+1), shuffle(1:n), (-1).^rand(Bool,n))
Example usage:
julia> randspermmat(5)
5×5 SparseMatrixCSC{Int64, Int64} with 5 stored entries:
⋅ ⋅ 1 ⋅ ⋅
⋅ 1 ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ 1
-1 ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ -1 ⋅
Storage-wise this is much better than a full matrix, and the generation speed is also better, the bigger the matrix is.
ADDITION: This is common enough to appear in another package LuxurySparse.jl with even simpler definition possible:
using LuxurySparse, Random
randspermmat_alt(n) =
PermMatrix(shuffle(1:n),(-1).^rand(Bool,n))
This package is even more efficient and might warrant a look depending on optimization required. A link: LuxurySparse package doc

You can simply shuffle row indices and place (1,-1) randomly in each column based on the shuffled row index.
function bipolar(siz)
m = n = siz
A = zeros(Int,m,n)
rowind = shuffle(1:m)
for (j,i) in enumerate(rowind)
A[i,j] = rand((-1,1))
end
A
end
Example run:
bipolar(5)
5×5 Matrix{Int64}:
0 0 1 0 0
0 0 0 0 1
0 0 0 -1 0
1 0 0 0 0
0 1 0 0 0

Related

Unclear behaviour of Symmetric() on sparse matrices

I am trying to have a better understanding on how the Symmetric() function acts on sparseCSC matrices.
I am storing the lower triangular portion of a symmetric matrix A. I then created sA = Symmetric(A) to allow Julia libraries functions as "\" and "eigs" to treat the matrix as symmetric.
If I want to efficiently modify the elements of sA, am I forced to operate on A? I mean, from A I can access the structure attributes as nzval and change its values, yet from sA it seems that I can only access the data using standard slicing operations for dense matrices.
For example, let us assume I want to add at position [7,3] a certain value X. Using sparse matrices representation I would just use a binary search on the rows associated to column 3 of A and then add the value at the proper entry of A.nzval.
on the other hand, on sA it looks that I can only call sA[7,3] = X.
Is there a way to access the structure attributes directly from sA? Keeping both A and sA as references to the same object does not look like a clean idea, yet I am unsure on how to avoid it.
While this may or may not be part of the public API, it looks like "keeping A around" is indeed exactly what Symmetric(A) does internally anyways:
julia> A = sprand(10,10,0.03)
10×10 SparseMatrixCSC{Float64, Int64} with 2 stored entries:
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ 0.437621 ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ 0.913864 ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
julia> sA = Symmetric(A)
10×10 Symmetric{Float64, SparseMatrixCSC{Float64, Int64}}:
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.437621 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.437621 0.0 0.0 0.913864 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.913864 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.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
julia> sA.<TAB>
data uplo
julia> sA.data
10×10 SparseMatrixCSC{Float64, Int64} with 2 stored entries:
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ 0.437621 ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ 0.913864 ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
julia> sA.data === A
true
julia> sA.data.<TAB>
colptr m n nzval rowval
Given this, I suppose you could forget about A and operate on sA.data -- but by the same token, keeping around your own reference to A is, given this implementation, nothing worse than having two names for the same variable, which isn't generally a major problem anyways.

Passing multiple arguments as one in Julia

I am trying to make a diagonal block matrix in Julia. I have an nxn array that I want to make P copies of as a block matrix down the diagonal and the rest of the matrix is sparse.
If arr is my array, I know I can use:
blockdiag(sparse(arr),sparse(arr))
to create a block with P=2 copies of the array down the diagonal.
However, for large P, how can I do this in a general way with variable P?
I tried making an array that is (nxnxP), however BlockDiag() does not accept a 3D array.
fill can repeat elements without actually making a copy.
Hence you can just do:
blockdiag(fill(sparse(arr), 2)...)
Here is a full Julia session:
julia> using SparseArrays
julia> arr=Matrix(sprand(Float64,3,3,0.25))
3×3 Matrix{Float64}:
0.0 0.016897 0.0
0.219705 0.0 0.0
0.0 0.0 0.893547
julia> blockdiag(fill(sparse(arr), 2)...)
6×6 SparseMatrixCSC{Float64, Int64} with 6 stored entries:
⋅ 0.016897 ⋅ ⋅ ⋅ ⋅
0.219705 ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ 0.893547 ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ 0.016897 ⋅
⋅ ⋅ ⋅ 0.219705 ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ 0.893547

What is the explanation for being able to simplify 'A^(B^C) mod prim' such that it is efficiently computable?

Prelude
We want compute the modular exponentiation A(BC) mod p = ?, where A, B, C, and p are known and p is a prim number. For example: 243mod 23 = 6
If we compute it in a straightforward way, first BC = e, and then Ae = n, and finally n mod p; we will run into the problem of creating (potentially) very large intermediary results for e and n. For example: e = 43 = 64, n = 264 ≈ 1.845x1019, and finally n mod 23 = 6
However, doing it in the straightforward way we did not take advantage of the fact that p is a prim number and that we are doing modular exponentiation. And also doing so, we will run into problems computing the result with a computer program in terms of time (CPU) and space (memory).
(Yes, we could do fast modular exponentiation using the identity (a ⋅ b) mod m = [(a mod m) ⋅ (b mod m)] mod m by first reducing A(BC) mod p to Ae mode p. For exmaple A2 mod p = (A ⋅ A) mod p = [(A mod p) ⋅ (A mod p)] mod p – but that is not where we want to go with this).
The smart way – use Fermat's little theorem
As documented in Find power of power under mod of a prime on GeeksforGeeks and the origin of this question, our exponent BC in A(BC) mod p can be expressed differently using Fermat's little theorem.
Fermat's little theorem states: a(p - 1) ≡ 1 (mod p) if p is a prime
Leading to following transformations:
It is possible to rewrite the exponent BC as x ⋅ (p - 1) + y
Using that alternate expression our ABC becomes Ax ⋅ (p - 1) + y = Ax ⋅ (p - 1) ⋅ Ay
Using Fermat's little theorem Ax ⋅ (p - 1) = 1; computing A(BC) mod p becomes computing Ay
Using BC = x ⋅ (p - 1) + y then y can be written as BC mod (p - 1)
From the above we get A(BC) mod p = (Ay) mod p
And with all of that we can compute A(BC) mod p in two steps while keeping the intermediary results small.
y = (BC) mod (p - 1)
result = (Ay) mod p
For example: 243mod 23
y = 43 mod (23 - 1) = 64 mod 22 = 20
result = 220 mod 23 = 1048576 mod 23 = 6
Question
My question is about above transformations, and I could not find an (easy to understand) explanation anywhere. Also intensly looking at Fermat's little theorem did not help. Possibly these transformations should be obvious, but it is simply not clear to me.
In particular, I do not understand why the exponent BC can be expressed as x ⋅ (p - 1) + y. – What is the reasoning behind this?
And also, why should it be "obvious" when using Fermat's little theorem:
a(p - 1) ≡ 1 (mod p) that Ax ⋅ (p - 1) = 1?
It would be great if someone could explain those transformations in an easy understandable way.
Let me address the two main questions you have:
In particular, I do not understand why the exponent BC can be expressed as x ⋅ (p - 1) + y. – What is the reasoning behind this?
Any integer k can be expressed as k = xm + y for some modulus m. Think of it as dividing k by m, and getting the quotient x and the remainder y. So let k = BC and m = p - 1 and tada.
If it helps you understand, an analogy is that you can turn any amount of minutes into "hours + minutes", when m = 60, then x = hours, y = remaining minutes.
And also, why should it be "obvious" when using Fermat's little theorem:
a(p - 1) ≡ 1 (mod p) that Ax ⋅ (p - 1) = 1?
Say we have a(p - 1) ≡ 1 (mod p). What happens if we multiply both sides by a(p - 1)? We get:
    a(p - 1) a(p - 1) ≡ a(p - 1) (mod p)
    a(p - 1) + (p - 1) ≡ 1 (mod p)             (zxzy = zx+y and the right hand side is equivalent to 1 as we've seen before)
    a2(p - 1) ≡ 1 (mod p)
We can repeatedly multiply both sides by a(p - 1) to get a3(p - 1), a4(p - 1), etc, so we say that for any integer x we have ax(p - 1) ≡ 1 (mod p).

Prove Number of Multiplications in Exponentiation by Squaring Algorithm

I am trying to find the number of multiplications required when executing an algorithm which uses Exponentiation by Squaring I was reading about on Wikipedia. The section, Computational Complexity, mentions that the algorithm requires at most floor(log n). How could I go about proving this?
I have this pseudocode:
expo(a, n)
if n == 0
return 1
if n == 1
return a
if n is even
b = expo(a, n/2)
return b*b
return a * expo(a, n-1)
With this, I also have the following relation
Number of multiplications = T(n)
T(n) = 0 if n<2; a*a^(n-1) if n is odd; (a^(n/2))^2 is n is even
I've attempted using bit-strings representing the base, a, and noting binary operations which need to be completed. i.e. 5 = 101_2. All 1's require inverting and then bit-shifting to the right. All 0's simply require bit-shifting to the right. These operations then can represent multiplication, as described by this chart I produced:
exponent n 0 1 2 3 4 5 6 7 8
bits in n 1 1 2 2 3 3 3 3 4
0-bits in n 1 0 1 0 2 1 1 0 3
1-bits in n 0 1 1 2 1 2 2 1 1
binary operations for a^n 0 0 1 2 2 3 3 4 3
multiplications for a^n 0 0 1 2 2 3 3 4 3
Edit
As pointed out by Henry in the comments below, the number of multiplications can be found using # of bits in binary representation + # of 1 bits in binary representation - 1. To prevent getting lost in the math, I will assume the amount of 1-bits is given by some function b(n). Then, T(n) = floor(log_2 n) + b(n) - 1
Proving for n = 2:
2_10 = 10_2 -> b(2) = 1
-> T(2) = floor(log_2 2) + b(2) - 1 = 1 + 1 - 1 = 1
This agrees with the observation table above.
Assume true for k.
Prove for k+1:
T(k+1) = floor(log_2 (k+1)) + b(k+1) - 1
After this formula, in terms of k+1, I am not so sure what to do. I would appreciate any insight.

Solving recurrence equation by substituion

I am trying to solve T(n) = sqrt(n)*T(sqrt(n))+sqrt(n) by drawing a reccurence tree and solving it be the substitution method. But I am having a hard time wrapping my head around how the sqrt method will affect this process and I am looking for some pointers if possible
Much appreciated!
You can write T(n) = sqrt(n)⋅T(sqrt(n)) + sqrt(n) as T(n) = n1/2 + n3/4 + n7/8 + ...
We know Σi=1,...,∞ 2-i = 1, so you can say
T(n) = n1/2 + n3/4 + n7/8 + ... < n + n + n + ...
Now you only have to compute the length of the sum by solving n2-x < 2 and you get something like x ≈ log log n.
So the solution is T(n) = O(n ⋅ log log n).
Sorry, you was looking for a solution using the substitun method. I never done this so I read a discription on this site.
Let T(sqrt(n)) = k ⋅ sqrt(n) ⋅ log log sqrt(n) + O(sqrt(n)) for constant k.
T(n) = sqrt(n) ⋅ k ⋅ sqrt(n) ⋅ log log sqrt(n) + sqrt(n) + O(sqrt(n))
= k ⋅ n ⋅ log (0.5 log n) + sqrt(n) + O(sqrt(n))
= k ⋅ n ⋅ log log n + log 0.5 + sqrt(n) + O(sqrt(n))
= k ⋅ n ⋅ log log n + O(sqrt(n))
= O(n log log n)
I hope this helps.

Resources