How to assign off-diagonal entries in SymTridiagonal matrix in julia? - julia

The SymTridiagonal data type in Julia is not letting me assign non-diagonal values to anything other than zero. I get this error: ArgumentError: cannot set off-diagonal entry (2, 1).
I need to assign non-diagonal values because I am trying to implement the ImplicitSymmetricQRStep algorithm which needs to do that in the process.

It is indeed not possible to set the off diagonal values of SymTridiagonal matrix - why this decision was taken I cannot say.
I see now two alternatives:
1) In Julia the fields of a structure are not hidden, so it is possible to change the value that way. This is dangerous though, as the internal structure of that matrix might change in future versions without any warnings. Here is an example of how you would do that:
using LinearAlgebra: SymTridiagonal
a = SymTridiagonal([1 2 0; 2 1 2; 0 2 1)] # 1 on diagonal, 2 on off diagonals
a.ev[1] = 4 # a[1, 2] == 4 and a[2, 1] == 4
2) You could also use the Tridiagonal matrix type, that is also in the LinearAlgebra package; this type allows one to set the off diagonal entries. Then you just have to make sure yourself that you don't violate the symmetric properties of that matrix i.e if you set a[i, j] then you also have to set a[j, i] to the same value.

Related

R: How to interpret square brackets with forms like y[i : j - k]

Can you help me understand how R interprets square brackets with forms such as y[i:j - k]?
dummy data:
y <- c(1, 2, 3, 5, 7, 8)
Here's what I do understand:
y[i] is the ith element of vector y.
y[i:j] is the ith to jth element (inclusive) of vector y.
y[-i] is vector y without the first i elements. etc. etc.
However, what I don't understand is what happens when you start mixing these options, and I haven't found a good resource for explaining it.
For example:
y[1-1:4]
[1] 5 7 8
So y[1-1:4] returns the vector without the first three elements. But why?
and
y[1-4]
[1] 1 2 5 7 8
So y[1-4] returns the vector without the third element. Is that because 1-4 = -3 and it's interpretting it the same as y[-3]? If so, that doesn't seem consistent with my previous example where y[1-1:4] would presumably be interpretted as y[0:4], but that isn't the case.
and
y[1:1+2-1]
[1] 2
Why does this return the second element? I encountered this while I was trying to code something along the lines of: y[i:i + j - k] and it took me a while to figure out that I should write y[i:(i + j - k)] so the parenthesis captured the whole of the right-hand-side of the colon. But I still can't figure out what logic R was doing when I didn't have those brackets.
Thanks!
It's best to look closer at precedence and the integer sequences you use for subsetting. These are evaluated before subsetting with []. Note that - is a function with two arguments (1, 1:4) which are evaluated beforehand and so
> 1-1:4
[1] 0 -1 -2 -3
Negative indices in [] mean exclusion of the corresponding elements. There is no "0" element (and so subsetting at 0 returns an empty vector of the present type -- numeric(0)). We thus expect y[1-1:4] to drop the first three elements in y and return the remainder.
As you write correctly y[1-4] is y[-3], i.e. omission of the third element.
Similar as above, in 1:1+2-1, 1:1 evaluates to a one-element vector 1, the rest is simple arithmetic.
For more on operator precedence, see Hadley's excellent book.

Identity matrix in Julia

I'm trying to construct the identity matrix in Julia 1.1. After looking at the documentation I found that I could compute a 4x4 Identity matrix as follows:
julia> Id4 =1* Matrix(I, 4, 4)
4×4 Array{Int64,2}:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
Is this the most julianic way of coding it or is there a better/shorter way, as it is an often used matrix?
Given using LinearAlgebra, the most julianic way of expressing the identity matrix is:
I
This answer may seem trite, but it is also kind of profound. The whole point of the operator I is that in the vast majority of cases where users want an identity matrix, it is not necessary to actually instantiate that matrix.
Let's say you want a 1000x1000 identity matrix. Why waste time building the entire matrix, when you could just use I, noting that sizeof(I) evaluates to 1 (ie the size of the object is 1 byte). All functions in base Julia (including LinearAlgebra) understand what I is, and can use it appropriately without having to waste time building the actual matrix it represents first.
Now, it may be the case that for some reason you need to specify the type of the elements of your identity matrix. Note:
julia> I
UniformScaling{Bool}
true*I
so in this case, you are using a notional identity matrix with a diagonal of true and off-diagonal of false. This is sufficient in many cases, even if your other matrices are Int or Float64. Internally, Julia will use methods that specialize on the types. However, if you want to specify your identity matrix to contain integers or floats, use:
julia> 1I
UniformScaling{Int64}
1*I
julia> 1.0I
UniformScaling{Float64}
1.0*I
Note that sizeof(1I) evaluates to 8, indicating the notional Int64 types of the members of that matrix.
Also note that you can use e.g. 5I if you want a notional matrix with 5 on the diagonal and 0 elsewhere.
In some cases (and these cases are much rarer than many might think), you may need to actually build the matrix. In this case, you can use e.g.:
Matrix(1I, 3, 3) # Identity matrix of Int type
Matrix(1.0I, 3, 3) # Identity matrix of Float64 type
Matrix(I, 3, 3) # Identity matrix of Bool type
Bogumił has also pointed out in the comments that if you are uncomfortable with implying the type of the output in the first argument of the constructors above, you can also use the (slightly more verbose):
Matrix{Int}(I, 3, 3) # Identity matrix of Int type
Matrix{Float64}(I, 3, 3) # Identity matrix of Float64 type
Matrix{Bool}(I, 3, 3) # Identity matrix of Bool type
and specify the type explicitly.
But really, the only times you would probably need to do this are as follows:
When you want to input an identity matrix into a function in a package written in such a way that the input must be a concrete matrix type.
When you want to start out with an identity matrix but then mutate it in place into something else via one or several transformations.

Generate Unique Combinations of Integers

I am looking for help with pseudo code (unless you are a user of Game Maker 8.0 by Mark Overmars and know the GML equivalent of what I need) for how to generate a list / array of unique combinations of a set of X number of integers which size is variable. It can be 1-5 or 1-1000.
For example:
IntegerList{1,2,3,4}
1,2
1,3
1,4
2,3
2,4
3,4
I feel like the math behind this is simple I just cant seem to wrap my head around it after checking multiple sources on how to do it in languages such as C++ and Java. Thanks everyone.
As there are not many details in the question, I assume:
Your input is a natural number n and the resulting array contains all natural numbers from 1 to n.
The expected output given by the combinations above, resembles a symmetric relation, i. e. in your case [1, 2] is considered the same as [2, 1].
Combinations [x, x] are excluded.
There are only combinations with 2 elements.
There is no List<> datatype or dynamic array, so the array length has to be known before creating the array.
The number of elements in your result is therefore the binomial coefficient m = n over 2 = n! / (2! * (n - 2)!) (which is 4! / (2! * (4 - 2)!) = 24 / 4 = 6 in your example) with ! being the factorial.
First, initializing the array with the first n natural numbers should be quite easy using the array element index. However, the index is a property of the array elements, so you don't need to initialize them in the first place.
You need 2 nested loops processing the array. The outer loop ranges i from 1 to n - 1, the inner loop ranges j from 2 to n. If your indexes start from 0 instead of 1, you have to take this into consideration for the loop limits. Now, you only need to fill your target array with the combinations [i, j]. To find the correct index in your target array, you should use a third counter variable, initialized with the first index and incremented at the end of the inner loop.
I agree, the math behind is not that hard and I think this explanation should suffice to develop the corresponding code yourself.

Generate sets from given overlap matrix

Note: I edited the original question to explain more precisely.
While I was doing a simulation for my new method, I needed to generate a special type of dataset consists of multiple subset. The problem is that there is some "shared" variables across the subsets, and the number of shared variable is called "overlap" here. Since the distribution of overlap proportion is given, I need to generate an appropriate list of variables and their overlap follows the given distribution. But I have failed to implement such algorithm...
I am not sure whether there is a specific algorithm for this kind of question,
but I have failed to find such thing after a long search.
I prefer R solution, but anything others also will be very appreciated. Please help me to solve this problem! Thank you so much in advance!
The below is a standardized explanation for my problem. I tried to explain as general as possible I can, but please give me any suggestion if it is not sufficient.
Purpose: Generate n sets from given overlap matrix of elements. Each set contains k elements.
Input: There is a n*n matrix whose (i,j)th cell value represents a number of overlapped elements from (i)th set to (j)th set.
Output: A list of k element identifiers (whatever can be used such as number) for n sets.
Assumption: The number of elements for each set is k, and it is same across all n sets. Hence, the input matrix is symmetric.
Example (assumes k=3 and n=3)
Input
3 1 0
1 3 1
0 1 3
Output
Set 1: A B C
Set 2: A D E
Set 3: D F G
In the above example input, (1,2)th and (2,1)th cells are 1 because set 1 and 2 share "A" element and vice versa, and diagonal cells are 3(=k) because each set shares all elements with itself.
I would repeat the following process until I had accounted for all the matrix entries:
1) Treat the matrix as the adjacency matrix of a graph, and find the largest clique in it. That is, find the largest possible set S of indexes such that for all i, j in set S M(i,j) > 0
2) Create an item that is in all of the sets which correspond to the indexes in S - in fact, if the minimum value of M(i,j) = v, create v such items.
3) subtract v from M(i,j) for all i, j in set S, accounting for the counts generated by the items you have just created.

Are these functions column-major or row-major?

I'm comparing two different linear math libraries for 3D graphics using matrices. Here are two similar Translate functions from the two libraries:
static Matrix4<T> Translate(T x, T y, T z)
{
Matrix4 m;
m.x.x = 1; m.x.y = 0; m.x.z = 0; m.x.w = 0;
m.y.x = 0; m.y.y = 1; m.y.z = 0; m.y.w = 0;
m.z.x = 0; m.z.y = 0; m.z.z = 1; m.z.w = 0;
m.w.x = x; m.w.y = y; m.w.z = z; m.w.w = 1;
return m;
}
(c++ library from SO user prideout)
static inline void mat4x4_translate(mat4x4 T, float x, float y, float z)
{
mat4x4_identity(T);
T[3][0] = x;
T[3][1] = y;
T[3][2] = z;
}
(linmath c library from SO user datenwolf)
I'm new to this stuff but I know that the order of matrix multiplication depends a lot on whether you are using a column-major or row-major format.
To my eyes, these two are using the same format, in that in both the first index is treated as the row, the second index is the column. That is, in both the x y z are applied to the same first index. This would imply to me row-major, and thus matrix multiplication is left associative (for example, you'd typically do a rotate * translate in that order).
I have used the first example many times in a left associative context and it has been working as expected. While I have not used the second, the author says it is right-associative, yet I'm having trouble seeing the difference between the formats of the two.
To my eyes, these two are using the same format, in that in both the first index is treated as the row, the second index is the column.
The looks may be deceiving, but in fact the first index in linmath.h is the column. C and C++ specify that in a multidimensional array defined like this
sometype a[n][m];
there are n times m elements of sometype in succession. If it is row or column major order solely depends on how you interpret the indices. Now OpenGL defines 4×4 matrices to be indexed in the following linear scheme
0 4 8 c
1 5 9 d
2 6 a e
3 7 b f
If you apply the rules of C++ multidimensional arrays you'd add the following column row designation
----> n
| 0 4 8 c
| 1 5 9 d
V 2 6 a e
m 3 7 b f
Which remaps the linear indices into 2-tuples of
0 -> 0,0
1 -> 0,1
2 -> 0,2
3 -> 0,3
4 -> 1,0
5 -> 1,1
6 -> 1,2
7 -> 1,3
8 -> 2,0
9 -> 2,1
a -> 2,2
b -> 2,3
c -> 3,0
d -> 3,1
e -> 3,2
f -> 3,3
Okay, OpenGL and some math libraries use column major ordering, fine. But why do it this way and break with the usual mathematical convention that in Mi,j the index i designates the row and j the column? Because it is make things look nicer. You see, matrix is just a bunch of vectors. Vectors that can and usually do form a coordinate base system.
Have a look at this picture:
The axes X, Y and Z are essentially vectors. They are defined as
X = (1,0,0)
Y = (0,1,0)
Z = (0,0,1)
Moment, does't that up there look like a identity matrix? Indeed it does and in fact it is!
However written as it is the matrix has been formed by stacking row vectors. And the rules for matrix multiplication essentially tell, that a matrix formed by row vectors, transforms row vectors into row vectors by left associative multiplication. Column major matrices transform column vectors into column vectors by right associative multiplication.
Now this is not really a problem, because left associative can do the same stuff as right associative can, you just have to swap rows for columns (i.e. transpose) everything and reverse the order of operands. However left<>right row<>column are just notational conventions in which we write things.
And the typical mathematical notation is (for example)
v_clip = P · V · M · v_local
This notation makes it intuitively visible what's going on. Furthermore in programming the key character = usually designates assignment from right to left. Some programming languages are more mathematically influenced, like Pascal or Delphi and write it :=. Anyway with row major ordering we'd have to write it
v_clip = v_local · M · V · P
and to the majority of mathematical folks this looks unnatural. Because, technically M, V and P are in fact linear operators (yes they're also matrices and linear transforms) and operators always go between the equality / assignment and the variable.
So that's why we use column major format: It looks nicer. Technically it could be done using row major format as well. And what does this have to do with the memory layout of matrices? Well, When you want to use a column major order notation, then you want direct access to the base vectors of the transformation matrices, without having them to extract them element by element. With storing numbers in a column major format, all it takes to access a certain base vector of a matrix is a simple offset in linear memory.
I can't speak for the code example of the other library, but I'd strongly assume, that it treats first index as the slower incrementing index as well, which makes it work in column major if subjected to the notations of OpenGL. Remember: column major & right associativity == row major & left associativity.
The fragments posted are not enough to answer the question. They could be row-major matrices stored in row order, or column-major matrices stored in column order.
It may be more obvious if you look at how a vector is treated when multiplied with an appropriate matrix. In a row-major system, you would expect the vector to be treated as a single row matrix, whereas in a column-major system it would similarly be a single column matrix. That then dictates how a vector and a matrix may be multiplied. You can only multiply a vector with a matrix as either a single column on the right, or a single row on the left.
The GL convention is column-major, so a vector is multiplied to the right.
D3D is row-major, so vectors are rows and are multiplied to the left.
This needs to be taken into account when concatenating transforms, so that they are applied in the correct order.
i.e:
GL:
V' = CAMERA * WORLD * LOCAL * V
D3D:
V' = V * LOCAL * WORLD * CAMERA
However they choose to store their matrices such that the in-memory representations are actually the same (until we get into shaders and some representations need to be transposed...)

Resources