# Julia Intro (for APMA 2550)
Much of this information is found easily online; this is meant as a quick distillation of how to do some things/ move over from MATLAB.
To motivate this, Julia is a language designed for scientific applications (e.g. numerical methods!) that takes the best of many worlds. Of course, Python, C++, and MATLAB rank among the most popular langauges for scientific applications, but each has a drawback: because of its abstractions and run-time specifications, Python is quite slow; C/C++ have relatively high barriers to entry and make it quite easy to shoot yourself in the foot; MATLAB is proprietary and also interpreted (as opposed to compiled), and its only supported editor only offers a light mode --- unacceptable!
Julia essentially took all the nice features from each (speed, ease of use, and utility), and it also boasts a number of really nice features that they display prominently on their [website](https://julialang.org). In particular, it offers LaTeX completion in your code (i.e., you can have a $\lambda$ in your code by typing `\lambda`, and so on), is dynamically typed/ feels like a scripting language (i.e., programming is quite similar to programming in Python), and is open source. Huge libraries have been built over the past few years, and development is active. Julia also supports Jupyter Notebooks (make sure to read below if this is of interest).
In fewer words, Julia is the prodigy child of C++, Python with Anaconda, and MATLAB that does more than everything you could have asked for.
## Installation
This is relatively straightforward for local. Download and run the executable, if you're on macOS/ Windows. On Linux, you'll need to download the binaries off their website, place it wherever, and add that wherever to your PATH as usual: `export PATH=$PATH:wherever/julia-1.x.x/bin`. Your distro probably has it packaged already on whatever repository it uses, but it's likely out of date -- perhaps woefully so, like it was for me -- so it may be best to just stick with manual installation, since it's just placing the downloaded folder somewhere and adding to PATH.
Installing extra packages is straightforward, as expected, on both local and Jupyter notebook environments. `using Pkg` and `Pkg.add("package_name")` one after the other will do the trick.
## Using Julia
In general, you should be able to find whatever you're looking for in the [docs](https://docs.julialang.org/en/v1/) or on [JuliaHub](https://juliahub.com/ui/Packages). [JuliaPackages](https://juliapackages.com/) and [Julia.jl](https://github.com/svaksha/Julia.jl) might also be of use, but I'd stick to JuliaHub for the most part.
#### Linear Algebra
As per the intents of the language, most of this is built-in/ standard library and should feel almost identical to MATLAB. I'd suggest at least skimming the beginning of [these docs](https://docs.julialang.org/en/v1/stdlib/LinearAlgebra/). In particular, the library is loaded with `using LinearAlgebra`.
#### Some numerics for PDEs
I suppose this bit isn't super relevant to our purposes, but for future reference.
It's probably clear by this point that this is a large topic in scientific computation. [This](https://nextjournal.com/sosiris-de/pde-2018) might be worth a read; it's from a JuliaCon workshop a few years back.
There's a [FEniCS port for Julia](https://github.com/SciML/FEniCS.jl), but it's not ideal, since we're in part adding yet another abstraction. I'd generally recommend avoiding ports for these reasons and searching for a Julia-based/ -focused package for your needs. It's likely that you'll otherwise have to sacrifice something -- probably Julia's nice typing system.
#### Visualization
JuliaPlots is the standard. Really pretty, and pretty easy to use (reminds me of Seaborn -- which I recommend checking out for Python if you haven't already. Handles a lot of the annoying parts of Matplotlib and generates some really nice looking things by default). The documentation can be found [here](https://docs.juliaplots.org/latest/).
#### Jupyter Notebooks
I'll assume you have Python and [Anaconda](https://www.anaconda.com/products/individual) installed already.
Additionally, you'll need the [IJulia](https://julialang.github.io/IJulia.jl/stable/) package, which offers the kernels that you'll need for your Jupyter environment to work with Julia, since it does not natively support the language. As above, `using Pkg` and `Pkg.add("IJulia")` will do the trick. Test with e.g. `Pkg.add("Plots")` or `println("Hello world!)"`.
#### Parallelization/ GPU Acceleration
If this is more your speed, would recommend checking out [Julia.jl repo's list](https://github.com/svaksha/Julia.jl/blob/master/Super-Computing.md). It boasts decent CUDA/ NVIDIA support. [CUDA.jl](https://juliapackages.com/p/cuda) is the most popular CUDA interface for Julia and does not require the CUDA toolkit.