Linear Algebra in Julia - julia

I'm attempting to use Julia for some Linear Algebra. The documentation lists a number of functions suitable for working with matrices. Some of these work directly on running Julia e.g.
julia> ones(2,2)
2×2 Array{Float64,2}:
1.0 1.0
1.0 1.0
while others give an UndefVarError e.g.
julia> eye(2,2)
ERROR: UndefVarError: eye not defined
Stacktrace:
[1] top-level scope at none:0
Why am I only able to access some of the functions listed on the Linear Algebra section? https://michaelhatherly.github.io/julia-docs/en/latest/stdlib/linalg.html#Base.LinAlg.expm
I have also tried importing the LinearAlgebra package but this doesn't make a difference:
julia> using LinearAlgebra
julia> eye(2,2)
ERROR: UndefVarError: eye not defined
Stacktrace:
[1] top-level scope at none:0
In fact some functions now become available e.g. dot, whilst others which according to the documentation are also part of the Linear Algebra library continue to give an error:
julia> dot
ERROR: UndefVarError: dot not defined
julia> using LinearAlgebra
julia> dot
dot (generic function with 12 methods)
julia> vecdot
ERROR: UndefVarError: vecdot not defined
Both of the above functions are listed as Base.LinAlg.dot in the documentation.
The packages I currently have installed are:
(v1.0) pkg> status
Status `~/.julia/environments/v1.0/Project.toml`
[0c46a032] DifferentialEquations v5.3.1
[7073ff75] IJulia v1.13.0
[91a5bcdd] Plots v0.21.0
[37e2e46d] LinearAlgebra
[2f01184e] SparseArrays
This problem occurs for many other functions discussed on the linear algebra page:
julia> repmat([1, 2, 3], 2)
ERROR: UndefVarError: repmat not defined
Stacktrace:
[1] top-level scope at none:0
I have Julia vs1.01 installed

The documentation you linked to is not the official documentation, which is found at docs.julialang.org. The docs you linked to are an old version on some developer's website. That is the reason why it doesn't line up with the current Julia.

Related

key SymPy not found for parallel computing

Does SymPy.jl work for parallel computing?
#everywhere using SymPy
using LinearAlgebra
using SharedArrays, Distributed
julia> xx = Sym[]
julia> #syms x
julia> #sync #distributed for i = 1:3
xx = [xx, x]
end
Unhandled Task ERROR: On worker 3:
KeyError: key SymPy [24249f21-da20-56a4-8eb1-6a02cf4ae2e6] not found
https://github.com/JuliaPy/SymPy.jl/issues/483
Distributed is for multi-process (as opposed to multi-threaded) parallelism. Think of it as running multiple independent Julia sessions simultaneously. That means you need to declare your imports on all workers - the #everywhere macro is your friend here.
#everywhere using SymPy
will import the package on all workers, which then allows you to use its functionality across all of them in distributed workloads.

Julia Matrix{AbstractFloat} type question [duplicate]

This question already has answers here:
Question about Julia type syntax: Why is Array{Int32, 1} <: Array{Integer, 1} false?
(3 answers)
Closed 1 year ago.
Context
In Julia: what does the "<:" symbol mean?, the 2nd answer directly quoted the three Julia's documentation for the <: operator. The 3rd one puzzles me.
Problem
To make this question independent from the quoted question, I'll make a particular example.
julia> 1.3 isa AbstractFloat
true
julia> [1.3 1.3; 1.2 1.2] isa Matrix{Float64}
true
julia> [1.3 1.3; 1.2 1.2] isa Matrix{AbstractFloat}
false
From Julia's documentation, AbstractFloat is an abstract type for all floating values, e.g. Float32, Float64, etc. That's explains the first example. However, I can't understand why a matrix of Float64 isn't a matrix of AbstractFloat.
You have to do:
julia> [1.3 1.3; 1.2 1.2] isa Matrix{<:AbstractFloat}
true
as type parameters in Julia are invariant.
This is explained in detail here.
If the linked explanation is not clear please comment where you need additional info and I can expand on the problematic areas.
EDIT
An explanation from a different angle (maybe it will be also helpful).
As is explained here in Julia:
One particularly distinctive feature of Julia's type system is that concrete types may not subtype each other: all concrete types are final and may only have abstract types as their supertypes. While this might at first seem unduly restrictive, it has many beneficial consequences with surprisingly few drawbacks.
The reason for this is that concrete types have a concrete memory layout, and in particular Matrix{Float64} and Matrix{AbstactFloat} have a different memory layout. Knowing memory layout of an object is crucial if we want the compiler to emit efficient machine code.
Now both Matrix{AbstractFloat} and Matrix{Float64} are concrete types (they can have instances):
julia> Matrix{AbstractFloat}(undef,0,0)
0×0 Matrix{AbstractFloat}
julia> Matrix{Float64}(undef,0,0)
0×0 Matrix{Float64}
julia> isconcretetype(Matrix{AbstractFloat})
true
julia> isconcretetype(Matrix{Float64})
true
In consequence Matrix{Float64} cannot be a subtype of Matrix{AbstractFloat} (nor vice versa)

How to reset any function in Julia to its original state?

I am learning Julia, Here is something I am unable to figure out.
Case1: I started Julia console and overridden the default sqrt function with a number 10. So now the function doesn't work. To me coming from R its bit of surprise, In R usually even if we override a function it works because of the method dispatch. Clearly, Julia's way of doing it is different which is okay. But now I am unable to reset to its natural state. I have to restart Julia to make it(sqrt) work again.
julia> sqrt = 10
10
julia> sqrt(5)
ERROR: MethodError: objects of type Int64 are not callable
Stacktrace:
[1] top-level scope at REPL[2]:1
julia> sqrt = Nothing
Nothing
julia> sqrt(5)
ERROR: MethodError: no method matching Nothing(::Int64)
Closest candidates are:
Nothing() at boot.jl:324
Stacktrace:
[1] top-level scope at REPL[4]:1
Case2: I started Julia console and used sqrt function to calculate things and it worked. But now if I try to reset to a constant it's not working. (I am assuming its because its compiled already and hence can't be overridden).
julia> sqrt(7)
2.6457513110645907
julia> sqrt = 10
ERROR: cannot assign a value to variable Base.sqrt from module Main
Stacktrace:
[1] top-level scope at REPL[2]:1
My question is:
Is there any way to reset the function to original state without restarting Julia?
Also is my assumption for case2 is correct?
I am not sure if its already answered somewhere. I tried to find it out, but couldn't. I am still giving a read on this thing. But asking for help if anyone knows this. Thanks in advance.
AFAIU, the rationale for this behavior is as follows:
when you run sqrt(5) in a program, it means that you know about the sqrt function. If, later on, you try to assign a new value to sqrt, Julia forbids you to do so, on the grounds that sqrt in your program actually refers to the Base.sqrt function, which is a constant. (Note that the same is true of any function that got exported by a package you're using; there is no specificity related to Base here, except that you don't have to explicitly using Base in order to be able to call the functions it defines).
if you don't use sqrt first as a function, Julia can't assume that you know about Base.sqrt. So if the first mention of sqrt in your program is an assignment, it will happily create a new variable of that name. This makes Julia more future-proof: suppose that you write a program that declares and uses a variable named foo. As of Julia 1.5.3, no Base.foo function exists. But now imagine that Julia 1.6 introduces a Base.foo function. We wouldn't want such a change to break your existing code, which should continue working with newer Julia versions. Therefore the safe choice in this case consists in letting you freely declare a variable foo without worrying about the name collision with Base.foo.
Now in the case where you accidentally create in an interactive session a global variable that collides with an existing function, a simple solution would be to simply reassign your variable to the function from Base (or whichever module the original function came from):
julia> sqrt = 1
1
# Oops, looks like I made a mistake
julia> sqrt(2)
ERROR: MethodError: objects of type Int64 are not callable
Stacktrace:
[1] top-level scope at REPL[2]:1
# Let's try and fix it
julia> sqrt = Base.sqrt
sqrt (generic function with 20 methods)
julia> sqrt(2)
1.4142135623730951

Why union type not accepting one of its types in Julia?

Why union type Array{Union{Missing, Float64},1} is not accepting Array{Float64,1}
function somefn(; serie::Vector{Union{Missing, Float64}})
end
serie = [1.0, 2.0, 1.0, 4.0]
somefn(serie = serie)
ERROR: TypeError: in keyword argument serie, expected Array{Union{Missing, Float64},1}, got Array{Float64,1}
Stacktrace:
[1] (::var"#kw##somefn")(::NamedTuple{(:serie,),Tuple{Array{Float64,1}}}, ::typeof(somefn)) at ./none:0
[2] top-level scope at REPL[12]:1
One way to fix it is to remove Vector{Union{Missing, Float64}} from function signature, I don't want to do that, I want to explicitly limit possible types for function arguments to reduce the bugs and easier understand how function works.
The reason is explained in The Julia Manual in the section on Parametric Composite Types.
In short in Julia types, except tuples are invariant. Citing the documentation:
This last point is very important: even though Float64 <: Real we DO NOT have Point{Float64} <: Point{Real}.
The way to fix your code to work is to write either:
function somefn(; serie::Vector{<:Union{Missing, Float64}})
end
or
function somefn(; serie::Vector{T}) where {T<:Union{Missing, Float64}}
end
which is explained later in that section of the manual.
The key thing to understand is that Vector{<:Union{Missing, Float64}} matches all types whose parameter is a subtype of Union{Missing, Float64}, whereas in Vector{Union{Missing, Float64}} the parameter must match Union{Missing, Float64} exactly.
Therefore in your original code example the following call:
somefn(serie = Union{Float64,Missing}[1,2,3])
would work as type parameter would match.

How can I see the list of methods in a Julia Package

Is there a command in Julia that lists all the methods that are available in a package?
For example I load up Distributions
using Distributions
and now I would like to see what function to call to draw a random value from a normal distribution. Is there a good way to do this from inside of Julia without a google search?
Sort of, although I don't think its of much utility:
julia> using Distributions
julia> names(Distributions)
215-element Array{Symbol,1}:
:median
:logpdf
:logpmf!
:Chisq
:posterior_rand
:fit_mle!
:NegativeBinomial
:posterior_rand!
:ContinuousMatrixDistribution
:ValueSupport
:InverseGamma
:complete
:TDist
:NormalCanon
:SufficientStats
:Chi
:logpmf
:logdetcov
:Gumbel
:Sampleable
...
or non-programmatically, using
julia> whos(Distributions)
AbstractMixtureModel DataType
AbstractMvNormal DataType
Arcsine DataType
Bernoulli DataType
Beta DataType
BetaPrime DataType
Binomial DataType
I think that with the inclusion of an inbuilt documentation system in Julia 0.4, we'll get way more packages with docs available at the REPL.

Resources