<jupyter_start><jupyter_text>> This is one of the 100 recipes of the [IPython Cookbook](http://ipython-books.github.io/), the definitive guide to high-performance scientific computing and data science in Python.  5.12. Trying the Julia language in the notebook For this recipe, you need to install Julia and IJulia. You'll find the installation instructions in the book. 1. We can't avoid the customary *Hello World* example. The `println()` function displays a string and adds a line break at the end.<jupyter_code>println("Hello world!")<jupyter_output><empty_output><jupyter_text>2. We create a polymorphic function `f` that computes the expression $z*z+c$. We will notably evaluate this function on arrays, so we use elementwise operators with a dot (`.`) prefix.<jupyter_code>f(z, c) = z.*z .+ c<jupyter_output><empty_output><jupyter_text>3. Let's evaluate `f` on scalar complex numbers (the imaginary number $i$ is `1im`).<jupyter_code>f(2.0 + 1.0im, 1.0)<jupyter_output><empty_output><jupyter_text>4. Now, we create a `(2, 2)` matrix. Components are separated by a space, rows are separated by a semicolon (`;`). The type of this `Array` is automatically inferred from its components. The `Array` type is a built-in data type in Julia, similar, but not identical, to NumPy's `ndarray` type.<jupyter_code>z = [-1.0 - 1.0im  1.0 - 1.0im;
     -1.0 + 1.0im  1.0 + 1.0im]<jupyter_output><empty_output><jupyter_text>5. We can index arrays with brackets `[]`. A notable difference with Python is that indexing starts from 1 instead of 0. MATLAB has the same convention. Besides, the keyword `end` refers to the last item in that dimension.<jupyter_code>z[1,end]<jupyter_output><empty_output><jupyter_text>6. We can evaluate `f` on the matrix `z` and a scalar `c` (polymorphism).<jupyter_code>f(z, 0)<jupyter_output><empty_output><jupyter_text>7. Now, we create a function `julia` that computes a Julia set. Optional named arguments are separated from positional arguments by a semicolon (`;`). Julia's syntax for flow control is close from Python's, except that colons are dropped, indentation doesn't count, and block `end` keywords are mandatory.<jupyter_code>function julia(z, c; maxiter=200)
    for n = 1:maxiter
        if abs2(z) > 4.0
            return n-1
        end
        z = f(z, c)
    end
    return maxiter
end<jupyter_output><empty_output><jupyter_text>8. We can use Python packages from Julia. First, we have to install the `PyCall` package by using Julia's built-in package manager (`Pkg`). Once the package is installed, we can use it in the interactive session with `using PyCall`.<jupyter_code>Pkg.add("PyCall")
using PyCall<jupyter_output><empty_output><jupyter_text>9. We can import Python packages with the `@pyimport` **macro** (a metaprogramming feature in Julia). This macro is the equivalent of Python's `import` command.<jupyter_code>@pyimport numpy as np<jupyter_output><empty_output><jupyter_text>10. The `np` namespace is now available in the Julia interactive session. NumPy arrays are automatically converted to Julia `Array`s.<jupyter_code>z = np.linspace(-1., 1., 100)<jupyter_output><empty_output><jupyter_text>11. We can use list comprehensions to evaluate the function `julia` on many arguments.<jupyter_code>m = [julia(z[i], 0.5) for i=1:100]<jupyter_output><empty_output><jupyter_text>12. Let's try the Gadfly plotting package. This library offers a high-level plotting interface inspired by Grammar of Graphics. In the notebook, plots are interactive thanks to the **d3.js** library.<jupyter_code>Pkg.add("Gadfly")
using Gadfly
plot(x=1:100, y=m, Geom.point, Geom.line)<jupyter_output><empty_output><jupyter_text>13. Now, we compute a Julia set by using two nested loops. In general, and unlike Python, there is no significant performance penalty using `for` loops instead of vectorized operations in Julia. High-performance code can be written either with vectorized operations or `for` loops.<jupyter_code>@time m = [julia(complex(r, i), complex(-0.06, 0.67)) 
           for i = 1:-.001:-1,
               r = -1.5:.001:1.5];<jupyter_output><empty_output><jupyter_text>14. Finally, we use the `PyPlot` package to draw matplotlib figures in Julia.<jupyter_code>Pkg.add("PyPlot")
using PyPlot
imshow(m, cmap="RdGy", 
       extent=[-1.5, 1.5, -1, 1]);<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10790203327171904, 'fraction_numerical': 0.02356746765249538, 'mean_word_length': 4.99584487534626, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '448714', 'license': 'BSD-2-Clause', 'n_tokens_mistral': 1472, 'n_tokens_neox': 1380, 'n_words': 504, 'path': 'notebooks/chapter05_hpc/12_julia.ipynb', 'repo_name': 'khanparwaz/PythonProjects', 'size': '4328'}