Julia 1.0 released

I’ve generally had good luck searching with a term like “fft jl”. The “jl” is more specific than “julia”. It’s good for finding related packages.

8 Likes

Something like https://pkg.julialang.org/? It does not appear to be maintained amymore, but, provided packages came with a reasonable description, it was searchable.

1 Like

It might be nice to automatically insert a hyperlink that searches for “Julia fft” (or whatever function not found)? If anyone likes that idea then we can even have a couple of links going to discourse, stackoverflow, and more generally google.

1 Like

openSUSE has a “cnf” (command not found) utility that suggests a source and installation method when a known Unix command-line utility is not found in the PATH. E.g.

gibson@parmenides$ inkscape
If 'inkscape' is not a typo you can use command-not-found to lookup the package that contains it, like this:
    cnf inkscape
gibson@parmenides$ cnf inkscape
                        
The program 'inkscape' can be found in following packages:
  * inkscape [ path: /usr/bin/inkscape, repository: zypp (openSUSE-Leap-15.0-1) ]
  * inkscape [ path: /usr/bin/inkscape, repository: zypp (repo-oss) ]

Try installing with:
    sudo zypper install inkscape

Something like that for the Julia REPL help mode that searches standard libs would be very helpful.

2 Likes

Now we’re Googling for fft, while I remember the following top 5 were once Julia’s core-core-core:

Julia

SepcialFunctions were not so special, SparseArrays were as important as Julia, there was no using LinearAlgebra, no using Random, let alone the, ughhh, Random.Seed!(), etc. These were all available out-of-the box.

Most of the confusion that happened to many people after the release of Julia 1.0, was to a large part due to missing functionality that one day was the default. MATLAB is 13GB, and Julia is 50MB, what would happen if these top 5 were shipped inside a stdlib along with the core language? And no user is forced to load a package they don’t use in their project.

4 Likes

Maybe I was a little cranky at how long it took to upgrade my code, nevertheless if it was documented, it was not easy to find. Case in point for the Linear Algebra page which you linked to, note that the library name itself is has to be inferred from entries such as LinearAlgebra.cholesky further down the page, and the examples do not show a using or import statement with the actual library name.

The page name Linear Algebra is not the library name inasmuch as it has a space between Linear and Algebra. The fft library was also just a pure guess for me that it might be FFTW. I’m still not sure if that is the official library name or another external library. FFT does not produce useful search results from the v1.0 manual as far as I could tell.

Please help us make this better! Pull requests to improve documentation are greatly appreciated and often best-written by folks who just fell through the gaps in our existing docs. You can edit it directly on GitHub:

2 Likes

I will usually have quite a few transpose operations throughout the code, when using complex matrices. In many cases it’s to set up a judicious use of the matrix multiply operator, so that the inner dimensions line up or so that the answer is of the right dimension. In other cases it’s due to interfacing code from developers who are using rows where you would use columns etc. etc. I’m guessing that folks who don’t regularly use complex arrays might not appreciate all the use cases for non-conjugating transpose. One still wants a concise operator for it, rather than the cumbersome permutedims, for the same reason why you want to retain the ’ postfix operator.

I would recommend a change to the form Matrix.H and Matrix.T if the parsing semantics are weird or inconsistent, but we still want concise operators for these operations. (This is used in numpy for the Matrix class I believe)

As for hiding bugs with the broadcasting semantics, it’s happened to me and can be difficult to find in some cases. One simple situation occurs with a construct like this:
A = B .+ C
where C is perhaps the transpose of what you thought it was. So maybe B is N x N and C is supposed to be a 1 x N row vector but now its an N x 1 column vector. There will be no error due to size mismatches, but your result will be wrong.

Again I’m not really complaining about this, the new broadcasting rules are helpful, but one does have to be careful.

With regards to broadcasting, our rules are not new. In fact, they match Numpy’s rules (which predates Julia).

Given that Julia cares so much more about types and dimensionality than Numpy, I’ve also thought about restricting broadcast’s behavior by dimensionality… but you run into trouble very quickly since we don’t have a way to push an array into a higher dimension without adding leading singleton dimensions. The new Adjoint and Transpose infrastructure actually gives us the ability to push vectors into 2-dimensions without that leading singleton dimension, but in general this requires a whole new vocabulary of co-arrays to perform anything but the most trivial of broadcast operations.

Please don’t take anything I say personally. I do not have a dim view of your decision making process at all. Overall I’m very happy about Julia and it is the tool that we have always wanted for scientific computing.

I’m just pointing out a few things that raised my blood pressure during the conversion process, and certainly I do not intend my “constructive” criticism to bring about any hard feelings.

Now isn’t (A+1)+B = A+(1+B) still true if B is either a matching sized array or itself an elemental value or 1x1 array? I am referring to specifically the special broadcasting case of +(Array{T},{T}). It’s still commutative too.

So it can’t be that. The reason must have something to do with broadcasting semantics. I do not know how that’s implemented, but if there are code transformations that eventually turn the code into the + operator iterated over the array indices, then maybe there are use cases where it breaks broadcasting.

However I actually don’t think so. The reason I don’t think this is the case is that any such transformations would have to adhere to the stricter use of +, and thus the broader use of + that retains elemental broadcasting would still work.

1 Like

I think this is actually possible to with the new getproperty functionality, but it would be quite un-idiomatic. Dot-access is not used the same way in Julia as in Python, which follows standard OO-patterns. So, while possible, I think this would really stick out as a sore thumb.

1 Like

Well you might be right, if you think of .H and .T as methods acting on an array object. That’s not Julia at all.

However if you think of them as broadcasted operators, it makes sense in a weird way. The operators are recursive after all, applying to each element in the array if necessary.

I’ll just leave this here:

julia> Base.getproperty(x::Array, name::Symbol) = name == :ᵀ ? transpose(x) : getfield(x, name)

julia> x = rand(3,3)
3×3 Array{Float64,2}:
 0.509624  0.867343  0.0286342
 0.275996  0.225391  0.486106
 0.314572  0.189146  0.108956

julia> x.ᵀ
3×3 LinearAlgebra.Transpose{Float64,Array{Float64,2}}:
 0.509624   0.275996  0.314572
 0.867343   0.225391  0.189146
 0.0286342  0.486106  0.108956
3 Likes
function Base.getproperty(A::Matrix{Complex{T}}, d::Symbol) where {T}
    if d == :T
        return transpose(A)
    elseif d == :H
       return A'
    else
       error('Blah')
    end
end

julia> a = rand(ComplexF64, 3, 3)
3×3 Array{Complex{Float64},2}:
 0.292567+0.841058im   0.51117+0.214808im  0.233489+0.979637im
  0.11209+0.128048im  0.240232+0.522118im  0.939373+0.398387im
 0.475112+0.495519im  0.781652+0.457975im  0.449527+0.316821im

julia> a.H
3×3 LinearAlgebra.Adjoint{Complex{Float64},Array{Complex{Float64},2}}:
 0.292567-0.841058im   0.11209-0.128048im  0.475112-0.495519im
  0.51117-0.214808im  0.240232-0.522118im  0.781652-0.457975im
 0.233489-0.979637im  0.939373-0.398387im  0.449527-0.316821im

julia> a.T
3×3 LinearAlgebra.Transpose{Complex{Float64},Array{Complex{Float64},2}}:
 0.292567+0.841058im   0.11209+0.128048im  0.475112+0.495519im
  0.51117+0.214808im  0.240232+0.522118im  0.781652+0.457975im
 0.233489+0.979637im  0.939373+0.398387im  0.449527+0.316821im

julia> a.T == transpose(a)
true

julia> a.H == a'
true

Not recommending this, though!!

That was close…

1 Like

My implementation sucks, though, since it will now throw an error for all other field access :smiley: !!!

Nevertheless can I use this idiom in my code? I don’t know anything about the getproperty semantics. It might make my code a bit cleaner. In fact the atom editor annoyingly adds a matching ’ whenever you type a single quote.

I think this is type piracy… But you can do it. It’s even performant.

I think it’s OhMyREPL.jl doing that. There’s an issue: Don't add closing quotation symbol after parens · Issue #124 · KristofferC/OhMyREPL.jl · GitHub

Edit: Wait, actually the quote should not normally be closed directly after an identifier.

I just realized that finding FFT documentation is even harder than just finding fft in FFTW.jl. It’s actually located in AbstractFFTs.jl

I think this is just horrible from a users perspective. I’m not just confused where fft is (I can’t find it in the Julia docs) and even if I find it (in FFTW.jl) I have to go to AbstractFFTs.jl to find documentation.