# [−][src]Crate julia_set

Julia set boundary computation and rendering.

# Theory

Informally, the Julia set for a complex-valued function `f` (in Rust terms, `fn(Complex32) -> Complex32`) is a set of complex points for which an infinitely small perturbation can lead to drastic changes in the sequence of iterated function applications (that is, `f(z)`, `f(f(z))`, `f(f(f(z)))` and so on).

For many functions `f`, the iterated sequence may tend to infinity. Hence, the commonly used computational way to render the Julia set boundary is as follows:

1. For each complex value `z` within a rectangular area, perform steps 2-3.
2. Compute the minimum iteration `0 < i <= MAX_I` such that `|f(f(f(...(z)))| > R`. Here, `f` is applied `i` times; `R` is a positive real-valued constant (the infinity distance); `MAX_I` is a positive integer constant (maximum iteration count).
3. Associate `z` with a color depending on `i`. For example, `i == 1` may be rendered as black, `i == MAX_I` as white, and values between it may get the corresponding shades of gray.
4. Render the rectangular area as a (two-dimensional) image, with each pixel corresponding to a separate value of `z`.

This is exactly the way Julia set rendering is implemented in this crate.

# Backends

The crate supports several computational `Backend`s.

BackendCrate featureHardwareCrate dep(s)
`OpenCl``opencl_backend`GPU, CPU`ocl`
`Vulkan``vulkan_backend`GPU`vulkano`, `shaderc`
`Cpu``cpu_backend`CPU`rayon`
`Cpu``dyn_cpu_backend`CPU`rayon`

None of the backends are on by default. A backend can be enabled by switching on the corresponding crate feature. `dyn_cpu_backend` requires `cpu_backend` internally.

All backends except for `cpu_backend` require parsing the complex-valued `Function` from a string presentation, e.g., `"z * z - 0.4i"`. The `arithmetic-parser` crate is used for this purpose. For `cpu_backend`, the function is defined directly in Rust.

For efficiency and modularity, a `Backend` creates a program for each function. (In case of OpenCL, a program is a kernel, and in Vulkan a program is a compute shader.) The program can then be `Render`ed with various `Params`.

Backends targeting GPUs (i.e., `OpenCl` and `Vulkan`) should be much faster than CPU-based backends. Indeed, the rendering task is embarrassingly parallel (could be performed independently for each point).

# Examples

Using Rust function definition with `cpu_backend`:

```use julia_set::{Backend, Cpu, Params, Render};
use num_complex::Complex32;

let program = Cpu.create_program(|z: Complex32| z * z + Complex32::new(-0.4, 0.5))?;
let render_params = Params::new([50, 50], 4.0).with_infinity_distance(5.0);
let image = program.render(&render_params)?;
// Do something with the image...```

Using interpreted function definition with `dyn_cpu_backend`:

```use julia_set::{Backend, Cpu, Function, Params, Render};
use num_complex::Complex32;

let function: Function = "z * z - 0.4 + 0.5i".parse()?;
let program = Cpu.create_program(&function)?;
let render_params = Params::new([50, 50], 4.0).with_infinity_distance(5.0);
let image = program.render(&render_params)?;
// Do something with the image...```

## Modules

 transform Post-processing transforms on Julia set images.

## Structs

 Cpu `cpu_backend`Backend that uses CPU for computations. CpuProgram `cpu_backend`Programs output by the `Cpu` backend. Come in two varieties depending on the type param: native closures, or interpreted `Function`s. FnError `dyn_cpu_backend` or `opencl_backend` or `vulkan_backend`Error associated with creating a `Function`. Function `dyn_cpu_backend` or `opencl_backend` or `vulkan_backend`Parsed complex-valued function of a single variable. OpenCl `opencl_backend`Backend based on OpenCL. OpenClProgram `opencl_backend`Program produced by the `OpenCl` backend. Params Julia set rendering parameters. Vulkan `vulkan_backend`Backend based on Vulkan. VulkanProgram `vulkan_backend`Program produced by the `Vulkan` backend.

## Traits

 Backend Backend capable of converting an input (the type parameter) into a program. The program then can be used to `Render` the Julia set with various rendering `Params`. ComputePoint `cpu_backend`Complex-valued function of a single variable. Render Program for a specific `Backend` (e.g., OpenCL) corresponding to a specific Julia set. A single program can be rendered with different parameters (e.g., different output sizes), but the core settings (e.g., the complex-valued function describing the set) are fixed.

## Type Definitions

 ImageBuffer Image buffer output by a `Backend`.