|
3 | 3 | This page is designed to help *Ops users* understand the SciJava Ops concepts powering the framework. |
4 | 4 |
|
5 | 5 | ## Ops |
6 | | -An **algorithm** is a mathematical routine that transforms, interrogate, or refines input values into output values, and are used throughout scientific computing. |
| 6 | +An **algorithm** is a mathematical routine that transforms, interrogate, or refines input values into output values. Algorithms are used throughout scientific computing, and the fundamental [purpose](Purpose) of SciJava Ops is to facilitate their application. |
7 | 7 |
|
8 | | -SciJava Ops attempts to abstract algorithm implementations into a more abstract, language independent form, called an **Op**. Ops have: |
9 | | -* a **name**, defining its purpose. An Op's name describes *what* the Op does, but not *how* the Op does it. |
10 | | - * An Op adding two Java `Integer`s would be named `math.add` |
| 8 | +We do that by providing a framework for consistently defining and invoking algorithm implementations as **Ops**. Ops have: |
| 9 | +* a **name**, establishing its purpose. An Op's name describes *what* the Op does, but not *how* the Op does it. |
| 10 | + * An Op adding two numbers would be named `math.add`, as would an Op adding two images |
11 | 11 | * An Op convolving an image with a kernel might be named `filter.convolve`, *regardless* of whether it performs that convolution in the physical or frequency domain. |
12 | 12 | * a number of **inputs** and **outputs**, defined by language-specific **types**. |
13 | 13 | * A `math.add` Op might take two Java `Integer` inputs and return a Java `Integer` output |
14 | 14 | * A `filter.convolve` Op might take two OpenCV `Mat` inputs, storing the convolved result into an OpenCV `Mat` output *buffer*. |
15 | | -* behavior adhering to a **functional interface** defined below. |
| 15 | +* behavior adhering to one of the three **Op types** defined below. |
16 | 16 |
|
17 | 17 | ## Computers |
18 | 18 |
|
19 | | -A **Computer** accepts `n` immutable inputs and a **container** as input parameters. Their singular method, `compute()`, executes an algorithm and *stores the result within* the container parameter, overwriting its contents. |
| 19 | +**Computer Ops** accept any number of immutable inputs and exactly one mutable **container** as parameters. When the algorithm they define is executed, *the result is stored within* the container parameter, overwriting its contents. The initial contents of the container do not affect computation. |
20 | 20 |
|
21 | | -For example, consider the following pseudocode, which replaces the contents of a list of integers `outList` with the elementwise addition of integer `val` to the list of integers `inList`: |
| 21 | +For example, consider the following pseudocode, which populates a list of integers (`outList`) with the elementwise addition of an integer constant (`value`) to a provided list of integers (`inList`): |
22 | 22 | ```text |
23 | | -math.add(inList: list[int], val: int, outList: list[int]): |
| 23 | +math.add(inList: list[int], value: int, outList: list[int]): |
24 | 24 | outList.clear() |
25 | 25 | for i in 1..size(inList): |
26 | | - outList[i] = inList[i] + val |
27 | | - |
| 26 | + outList[i] = inList[i] + value |
28 | 27 | ``` |
29 | 28 |
|
30 | 29 | ## Functions |
31 | 30 |
|
32 | | -A **Function** accepts `n` immutable inputs as parameters. Their singular method, `apply()`, executes an algorithm and *returns* a new output object to the user. |
| 31 | +**Function Ops** accept any number of immutable inputs as parameters. When the algorithm they define is executed, *the result is returned* as a new output to the user. |
33 | 32 |
|
34 | | -For example, consider the following pseudocode, which returns a list of integers with the elementwise addition of integer `val` to the list of integers `inList`: |
| 33 | +For example, consider the following pseudocode, which creates a list of integers from the elementwise addition of an integer constant (`value`) to the provided list of integers (`inList`): |
35 | 34 | ```text |
36 | | -math.add(inList: list[int], val: int) -> list[int]: |
| 35 | +math.add(inList: list[int], value: int) -> list[int]: |
37 | 36 | outList = list() |
38 | 37 | for i in 1..size(inList): |
39 | | - outList[i] = inList[i] + val |
| 38 | + outList[i] = inList[i] + value |
40 | 39 | return outList |
41 | 40 | ``` |
42 | 41 |
|
43 | | -Creating a new output object on every execution is a double-edged sword: on one hand, it can be convenient to delegate creation to the Op. On the other hand, output creation can be expensive and unnecessary if the Op is called many times. |
| 42 | +An advantage of Functions is their convenience. However, output creation can be expensive and unnecessary if the Op is called many times. |
44 | 43 |
|
45 | 44 | ## Inplaces |
46 | 45 |
|
47 | | -A **Inplace** accepts `n` input parameters, **only one** of which is mutable. Their singular method, `mutate()`, executes an algorithm and *overwrites* the single mutable parameter with the algorithm results. |
| 46 | +**Inplace Ops** accept any number of input parameters, **exactly one** of which is mutable. When the algorithm they define is executed, *the mutable parameter is modified* as a result of computation. |
48 | 47 |
|
49 | | -For example, consider the following pseudocode, which mutates a list of integers `inList` by adding the integer `val` to each: |
| 48 | +For example, consider the following pseudocode, which modifies a provided list of integers (`inList`) by adding an integer constant (`value`) to each element: |
50 | 49 | ```text |
51 | | -math.add(inList: list[int], val: int): |
| 50 | +math.add(inList: list[int], value: int): |
52 | 51 | for i in 1..size(inList): |
53 | | - inList[i] = inList[i] + val |
| 52 | + inList[i] = inList[i] + value |
54 | 53 | ``` |
55 | 54 |
|
56 | | -A major advantage of Inplaces is the efficiency gained by the absence of an output buffer. On the other hand, the input data is lost through computation. |
| 55 | +An advantage of Inplaces is both the convenience and savings (in time and memory) of not creating an output. On the other hand, the input data is lost through computation, and some algorithms require the input to remain unmodified (e.g. for neighborhood calculations). |
57 | 56 |
|
58 | 57 | ## OpEnvironment |
59 | 58 |
|
60 | | -The Op environment collects all available Ops, and provides access to their functionality. `OpEnvironment` objects are instantiated using the line shown below, and once created will contain all available Ops: |
61 | | -```java |
62 | | -OpEnvironment ops = OpEnvironment.build(); |
63 | | -``` |
| 59 | +The **Op environment** collects all available Ops, and serves as a gateway for accessing their functionality. Obtaining an `OpEnvironment` is the first step for any Ops use. |
64 | 60 |
|
65 | 61 | With an `OpEnvironment`, users can: |
66 | 62 | * Find Ops, using the `OpEnvironment.help()` API (see [Searching For Ops](SearchingForOps.md)) |
67 | | -* Execute Ops, using the `OpEnvironment.op()` API (see [Calling Ops](CallingOps.md), and the `OpBuilder` section below.) |
| 63 | +* Execute Ops, using the `OpEnvironment.op()` API (see [Calling Ops](CallingOps.md)) |
68 | 64 |
|
69 | 65 | ## OpBuilder |
70 | 66 |
|
|
0 commit comments