Julia: Plugging Matrix Values into a Function - vector

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

Compute a discrete Fourier Transform matrix in Julia?

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.

Julia how to get coefficients out of SymPy solveset

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.

Partial derivatives in Julia

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

julia, linear algebra, is there a function finding all vectors orthogonal to the given one?

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

How to construct `g` such that `g(x0)(x1)(x2) == f(f(x0, x1), x2)`

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.

Resources