I have a given matrix PC1, which is a 3xn matrix. I would like to write a loop that calculates the magnitude (vector magnitude) of each line of our given matrix and rewrite it into a 1xn matrix. For magnitude I made the function:
function magnitude(x,y,z)
sqrt((x^2)+(y^2)+(z^2))
end
I want to be able to use this function if possible to again calculate the magnitude of each line of my matrix. I have tried the following:
for j in size(pc1[:,1])
B[j] = magnitude(pc1[1,j],a[2,j],a[3,j])
end
When I try this, I get an error reading:
"ArgumentError: Invalid index: 0.0 of type Float64"
Any suggestions on how to get rid of this error as well as make my for loop work would be wonderful.
Thanks!
Then you can do this:
#Suppose that my_mat is:
julia> my_mat
3×5 Matrix{Float64}:
0.146247 0.309755 0.0802212 0.810787 0.459134
0.810021 0.876092 0.89679 0.238271 0.852003
0.124778 0.590032 0.613531 0.0857502 0.524727
julia> function magnitude(x...)
x1, x2, x3 = x
#show x1, x2, x3
sqrt((x1^2)+(x2^2)+(x3^2))
end
magnitude (generic function with 1 method)
julia> magnitude.(eachrow(my_mat)...)
(x1, x2, x3) = (0.14624718982068596, 0.8100214466524703, 0.1247777052693978)
(x1, x2, x3) = (0.30975515637837503, 0.8760918202600901, 0.5900319505173406)
(x1, x2, x3) = (0.08022117017277575, 0.8967900297662494, 0.6135309351302954)
(x1, x2, x3) = (0.8107874182293756, 0.23827052138513005, 0.08575020171498149)
(x1, x2, x3) = (0.45913420665189597, 0.852002514985355, 0.5247268441565018)
5-element Vector{Float64}:
0.8325217476436908
1.1007374060423891
1.0895356818360262
0.8494128419174967
1.1009317718358742
As you can see, you don't need a for loop for this, and broadcasting can do what you need through the dot (.) operator.
But maybe you ask why I used eachrow and how I'm accessing each column through the eachrow function. Well, let's see an example to understand what's happening inside magnitude.(eachrow(my_mat)...):
The eachrow function returns a generator that iterates over the first dimension of the vector or matrix. Let's say I have a matrix named mat:
julia> mat = rand(2,2)
2×2 Matrix{Float64}:
0.541733 0.0644034
0.451938 0.612991
Now some_func.(eachrow(mat)...) is equivalent to these:
julia> some_func.([0.541733, 0.0644034], [0.451938, 0.612991])
# Which is equivalent to
julia> [some_func(0.541733, 0.451938),
some_func(0.0644034, 0.612991)
]
And this is how I managed to broadcast your function on each column using broadcasting.
Additional Notes
But I suggest you make your function robust and not limit it to specific dimensions (your function accepts three elements, which is usable only when you have a 3xn matrix). Let's make it better:
julia> function magnitude(x...)
sqrt(sum(x->x^2, x))
end
magnitude (generic function with 1 method)
One of the beautiful features of the sum function is that it can accept a function as its first positional argument and an iterable as its second positional argument; In this way, sum applies the given function on each element of the given iterable and then sum the results up. And now I apply it on my_mat through broadcasting:
julia> magnitude.(eachrow(my_mat)...)
5-element Vector{Float64}:
0.8325217476436908
1.1007374060423891
1.0895356818360262
0.8494128419174967
1.1009317718358742
The result is similar to before but not limited to a specific dimension!
Related
In Julia, I would like to randomly generate a discrete fourier transform matrix of size n by n. I am currently not sure how to how to do such. Does anyone perhaps know a way to do this in Julia?
As said in the comments, you can use the FFTW.jl package for this purpose:
julia> using FFTW
julia> n = 5;
julia> rnd = rand(1:100, n, n);
julia> fft(rnd)
5×5 Matrix{ComplexF64}:
1216.0+0.0im 65.8754+10.3181im 106.125+119.409im 106.125-119.409im 65.8754-10.3181im
160.529-95.3957im 177.376-31.8946im -28.6976+150.325im 52.8237+139.038im 82.2517-165.542im
-91.0288-22.1566im 136.676+28.1im -42.8763-97.2573im -97.7517+4.15021im 8.19756-13.5548im
-91.0288+22.1566im 8.19756+13.5548im -97.7517-4.15021im -42.8763+97.2573im 136.676-28.1im
160.529+95.3957im 82.2517+165.542im 52.8237-139.038im -28.6976-150.325im 177.376+31.8946im
And for a Real datatype, you can use the rfft function:
julia> let n = 5
rnd = rand(n, n)
rfft(rnd)
end
3×5 Matrix{ComplexF64}:
10.54+0.0im 1.15104+0.522166im -0.449373-0.686863im -0.449373+0.686863im 1.15104-0.522166im
-1.2319+0.3485im -0.622914-0.649385im 1.39743-0.733653im 1.66696+0.694317im -1.59092-0.578805im
0.501205+0.962713im 0.056338-0.207403im 0.0156042-0.181913im -1.87067-1.66951im -0.672603-0.969665im
It might rise the question that why the result is a 3x5 matrix:
According to the official doc about the rfft function:
"Multidimensional FFT of a real array A, exploiting the fact that the transform has conjugate symmetry in order to save roughly half the computational time and storage costs compared with fft. If A has size (n_1, ..., n_d), the result has size (div(n_1,2)+1, ..., n_d)."
It's also possible to first create a random nxn matrix with the eltype of ComplexF64 and perform the fft on it; For this create the rnd variable like rand(ComplexF64, n, n) in the above let block, and replace the rfft with fft function.
I'm using symbolic math in Julia. When I do the differentiation it comes out very nicely, but I cant get the coefficients out
using SymPy
#vars x y
z = x*(10 + 5*x + 4*y)
dz = diff(z,x)
x_s = solveset(dz,x)
how do I get the the coefficients out of x_s?
You can use elements to get the elements of a finite sets as an array:
julia> elements(s)
1-element Array{Sym,1}:
-2*y/5 - 1
To get the coefficients can be done different ways, but here we convert the value to a Polynomial type, then use its coeffs method:
julia> p = sympy.Poly(elements(s)[1], y)
Poly(-2/5*y - 1, y, domain='QQ')
julia> p.coeffs()
2-element Array{Sym,1}:
-2/5
-1
As per my comment, the following works but isn't exactly what I'd describe as pretty:
julia> x_s.__pyobject__.args[1].__pyobject__.args[1]
-1
julia> x_s.__pyobject__.args[1].__pyobject__.args[2]
-2⋅y
─────
5
julia> x_s.__pyobject__.args[1].__pyobject__.args[2].__pyobject__.args[1]
-2/5
I couldn't find an accessor function in Sympy.jl that simplifies this, but as you say this could be the basis for rolling your own.
I'm trying to numerically solve a nonlinear system of equations in Julia. I'm using Newthon method. The only thing I don't know how to do, is to compute an Jacobian matrix. So far I couldn't find the function to compute partial derivatives.
My system:
f(x1, x2) = 2*x2^2+x1^2
g(x1, x2) = (x1-1)^2 + (x2-1/2)^2
Thanks for your support,
Best regards,
Szymon.
Let me write as an answer what I already mentioned in the comments. You could use automatic differentiation to calculate the partial derivatives:
julia> using ForwardDiff
julia> f(x) = 2*x[2]^2+x[1]^2 # f must take a vector as input
f (generic function with 2 methods)
julia> g = x -> ForwardDiff.gradient(f, x); # g is now a function representing the gradient of f
julia> g([1,2]) # evaluate the partial derivatives (gradient) at some point x
2-element Array{Int64,1}:
2
8
For a given vector I would like to find the orthogonal basis around it,
i.e. the given vector normalized and randomly chosen basis of orthogonal sub-space.
Is there a convenient function for this in Julia?
The function you are looking for is called nullspace.
julia> x = randn(5);
julia> x⊥ = nullspace(x');
julia> x'x⊥
1×4 Array{Float64,2}:
7.69373e-16 -5.45785e-16 -4.27252e-17 1.26778e-16
You could define a function orth (if someonehasn't already done this)
orth(M) = qr(M)[1]
See here:
https://groups.google.com/forum/#!topic/julia-users/eG6a4tj7LGg and http://docs.julialang.org/en/release-0.4/stdlib/linalg/
Or from IterativeSolvers.jl:
orthogonalize{T}(v::Vector{T}, K::KrylovSubspace{T})
See:
https://github.com/JuliaMath/IterativeSolvers.jl
The following will calculate an orthogonal basis for matrix M
function orth(M::Matrix)
matrixRank = rank(M)
Ufactor = svdfact(M)[:U]
return Ufactor[:,1:matrixRank]
end
With julia documentation:
"""
orth(M)
Compute an orthogonal basis for matrix `A`.
Returns a matrix whose columns are the orthogonal vectors that constitute a basis for the range of A.
If the matrix is square/invertible, returns the `U` factor of `svdfact(A)`, otherwise the first *r* columns of U, where *r* is the rank of the matrix.
# Examples
```julia
julia> orth([1 8 12; 5 0 7])
2×2 Array{Float64,2}:
-0.895625 -0.44481
-0.44481 0.895625
```
```
julia> orth([1 8 12; 5 0 7 ; 6 4 1])
3×3 Array{Float64,2}:
-0.856421 0.468442 0.217036
-0.439069 -0.439714 -0.783498
-0.27159 -0.766298 0.582259
```
"""
function orth(M::Matrix)
matrixRank = rank(M)
Ufactor = svdfact(M)[:U]
return Ufactor[:,1:matrixRank]
end
Given arbitrary function f, how to construct function g such that for every x0, x1, ..., xn, g(x0)(x1)...(xn) equals f(...f(f(x0, x1), x2), ...), xn)?
EDIT
This is very similar to the question how to implement a function like sum(2)(3)(4)...(n) in python
At every point gn has to return both a function that can accept xn+1 and the value given by applying f to gn-1 and xn. Unless you are using a language that allows the return value to be or act as both types, this is impossible.