i am trying to write a general tensor operation in julia (matrix * tensor of known rank).
My tensor is an object with n indices (e.g. tensor(a_1,a_2,...,a_n) and my matrix only has an effect on the i'th index. Therefore it would be conventient to have an iterator with goes over every but the i'th index. Is there an easy function to implement this, or do you have an idea how to do it with good performance? I also need the result of the iterator in the CartesianIndex-form (i think), because i have to iterate over the last index in a matrix-vector-multiplication style.
My first idea was to get all permutations for the indices before and after the i'th one, but the generation of those seemed tedious...
I hope you can help me,
best regards,
lepmueller
It's not clear exactly what you are after. You can get an iterator over the indices that ignore the i'th row of a Matrix like
Iterators.filter(x->x[1] != i, CartesianIndices(a))
Is that useful for you, or could you edit the question to be more explicit?
FWIW, there is also a nice little package called InvertedIndices.jl which allows you to drop specific columns/rows like so:
julia> using InvertedIndices
julia> x = rand(4,4)
4×4 Array{Float64,2}:
0.779118 0.66097 0.335433 0.583011
0.284284 0.799394 0.353914 0.146769
0.716189 0.605426 0.2449 0.92238
0.140876 0.210152 0.810854 0.37236
julia> x[Not(2), Not(4)] # drop second row and 4th column
3×3 Array{Float64,2}:
0.779118 0.66097 0.335433
0.716189 0.605426 0.2449
0.140876 0.210152 0.810854
Related
I am a complete noob in Julia and its syntax. I am trying to follow this article on semi-definite-programming on Julia.
I would apprecieate if someone can help me figure out what the for loop in In[4] actually does:
for i in 1:m
A[:, (i-1)*n+1:i*n] .= random_mat_create(n)
b[i] = tr(A[:, (i-1)*n+1:i*n]*X_test)
end
To my understanding it should create a vector of matrices A (m of those) as well as an m-dimensional vector b. I am totally confused though on the indexing of A and the indexing of b.
I would like an explanation of the :, (i-1)*n+1:i*n part of this code. The reason I ask here is because I also dont know what to Google or what to search for in Julia documentation.
(i-1)*n+1:i*n creates a range from (i-1)*n + 1 to i*n. For example, if i=2 and n=10, this range becomes 11:20, so A[:, (i-1)*n+1:i*n] will grab all the rows of A (that's what : does), and columns 11-20.
There are two operations there that are not clear to you:
: operator. Consider a Matrix a = zeros(3,3). You could use array slicing operator (similarly to numpy or Matlab) to select the entire second columns as: a[1:end,2]. However, when selecting everything from start to the end those two values can be omitted and hence you can write a[:,2] (this always looked the easiest way for me to remember that)
. (dot) operator. Julia is very careful about what gets vectorized and what not. In numpy or R, vectorizing operations happens kind of always automatically. In Julia you have the control - but with the control comes the responsibility. Hence trying to assign values to the second column by writing a[:, 2] = 5.0 will throw an error because there is vector on the right and a scalar on the left. If you want to vectorize you need to tell that to Julia. Hence the dot operator .= means "perform element-wise assignment". Note that any Julia function or operator, even your own functions can be decorated by such dot .. Since this is a very important language feature have a look at https://docs.julialang.org/en/v1/manual/arrays/#Broadcasting
I have a matrix with many random values ranging from -600 to +600. These values are intermixed with each other inside of the matrix.
What I want to do is separate the negative values and positive values into their own matrices. Maybe even separating the values that are greater than 400 into its own matrix as well.
I'm fairly new with coding, so the first thing that popped in my head was an if statement. I am using Octave. I don't know if theres a better way to go about it, but I would appreciate all help I can get. Thanks
The best way to do this is to use logical indexing. You can create a logical matrix the size of your data based on the criteria you want.
So for example to get only the values that are negative:
negatives = your_data(your_data < 0);
And positive values
positives = your_data(your_data >= 0);
You can alter the expression used to generate the logical matrix to suit your needs.
Also if you're simply using Octave, you can stop tagging C++ since they are different languages.
In Maple, I have a matrix N and its elements N[i,j], If I modify the elements of this matrix as follows for example
>for j from 1 to 4 do
>print(F[i,j]=(diff(N[i,j],x)));
>od;od;
where the matrix elements are functions of x.
I've wanted to define new matrix elements
>BA[i,j]:=(diff(N[i,j],x)));
but I can't do this with Maple, through the above command. Can someone help me ?
Better than using a loop is simply BA:= diff~(N,x). The ~ can be appended to any operator to mean "apply the operator to each member of the container and return a new container containing the modified members."
Also, be careful about using print. Its only purpose is to print stuff on the screen from the middle (not the end) of a computation. It can't be used to change any stored values. Good programs use print very sparingly, if at all. The end result of a computation is displayed automatically, without needing a print command.
I was reading Parallel Computing docs of Julia, and having never done any parallel coding, I was left wanting a gentler intro. So, I thought of a (probably) simple problem that I couldn't figure out how to code in parallel Julia paradigm.
Let's say I have a matrix/dataframe df from some experiment. Its N rows are variables, and M columns are samples. I have a method pwCorr(..) that calculates pairwise correlation of rows. If I wanted an NxN matrix of all the pairwise correlations, I'd probably run a for-loop that'd iterate for N*N/2 (upper or lower triangle of the matrix) and fill in the values; however, this seems like a perfect thing to parallelize since each of the pwCorr() calls are independent of others. (Am I correct in thinking this way about what can be parallelized, and what cannot?)
To do this, I feel like I'd have to create a DArray that gets filled by a #parallel for loop. And if so, I'm not sure how this can be achieved in Julia. If that's not the right approach, I guess I don't even know where to begin.
This should work, first you need to propagate the top level variable (data) to all the workers:
for pid in workers()
remotecall(pid, x->(global data; data=x; nothing), data)
end
then perform the computation in chunks using the DArray constructor with some fancy indexing:
corrs = DArray((20,20)) do I
out=zeros(length(I[1]),length(I[2]))
for i=I[1], j=I[2]
if i<j
out[i-minimum(I[1])+1,j-minimum(I[2])+1]= 0.0
else
out[i-minimum(I[1])+1,j-minimum(I[2])+1] = cor(vec(data[i,:]), vec(data[j,:]))
end
end
out
end
In more detail, the DArray constructor takes a function which takes a tuple of index ranges and returns a chunk of the resulting matrix which corresponds to those index ranges. In the code above, I is the tuple of ranges with I[1] being the first range. You can see this more clearly with:
julia> DArray((10,10)) do I
println(I)
return zeros(length(I[1]),length(I[2]))
end
From worker 2: (1:10,1:5)
From worker 3: (1:10,6:10)
where you can see it split the array into two chunks on the second axis.
The trickiest part of the example was converting from these 'global' index ranges to local index ranges by subtracting off the minimum element and then adding back 1 for the 1 based indexing of Julia.
Hope that helps!
I have a matrix S(105 rows and 22 columns) and I need to find its orthogonal (when I multiply S with the orthogonal the result must be a zero matrix).I searched and the only command I found that seems to do what I want is nullspace[S] but the result is not the matrix I need.It is a matrix with 8 rows and 22 columns that it doesnt give me the result I want.I tried Transpose in case it got the matrix backwards but the multiplication cannot be done either.Is there anyone who knows about mathematica that can help me?Thanks.
I am not sure, if I understood your concept of an "orthogonal" matrix, which is usually defined differently. But if you are looking for a matrix T such that T.S == {{0,0,....},...} then
T = NullSpace[Transpose[S]];
Unless your 105*22-dimensional matrix S is highly degenerate, there is no solution such that S.T==0.
In this case, T = Transpose[NullSpace[S]] will most likely render {}.