Julia – 11 – operazioni matematiche e funzioni elementari – 2

Continuo da qui, copio qui.

Operatore `.` (punto, dot) vettorializzato
For every binary operation like `^`, there is a corresponding “dot” operation `.^` that is automatically defined to perform `^` element-by-element on arrays. For example, `[1,2,3] ^ 3` is not defined, since there is no standard mathematical meaning to “cubing” an array, but `[1,2,3] .^ 3` is defined as computing the elementwise (or “vectorized”) result `[1^3, 2^3, 3^3]`. Similarly for unary operators like `!` or `√`, there is a corresponding `.√` that applies the operator elementwise.

Nota: `√` è `U+221A`, square root, e noi vecchi usiamo `sqrt()`, voi fate voi 😜

More specifically, `a .^ b` is parsed as the “dot” call `(^).(a,b)`, which performs a broadcast operation: it can combine arrays and scalars, arrays of the same size (performing the operation elementwise), and even arrays of different shapes (e.g. combining row and column vectors to produce a matrix). Moreover, like all vectorized “dot calls,” these “dot operators” are fusing. For example, if you compute `2 .* A.^2 .+ sin.(A)` (or equivalently `@. 2A^2 + sin(A)`, using the `@.` macro) for an array `A`, it performs a single loop over `A`, computing `2a^2 + sin(a)` for each element of `A`. In particular, nested dot calls like `f`.(g.(x)) are fused, and “adjacent” binary operators like `x .+ 3 .* x.^2` are equivalent to nested dot calls `(+).(x, (*).(3, (^).(x, 2)))`.

Furthermore, “dotted” updating operators like `a .+= b` (or `@. a += b`) are parsed as `a .= a .+ b`, where `.=` is a fused in-place assignment operation (see the dot syntax documentation [prossimamente]).

Note the dot syntax is also applicable to user-defined operators. For example, if you define `⊗(A,B) = kron(A,B)` to give a convenient infix syntax `A ⊗ B` for Kronecker products (`kron`), then `[A,B] .⊗ [C,D]` will compute `[A⊗C, B⊗D]` with no additional coding.

Uhmmm… tante cose qui che andranno spiegate in futuro. per adesso: mystero 😯

Comparazioni numeriche
Standard comparison operations are defined for all the primitive numeric types:

``````Operator Name
==       equality
!=, ≠    inequality
<        less than
<=, ≤    less than or equal to
>        greater than
>=, ≥	 greater than or equal to``````

Codici Unicode: `≠` `U+2260`, `≤` `U+2264`, `≥` `U+2265`; naturalmente noi vecchi… 😜

Integers are compared in the standard manner – by comparison of bits. Floating-point numbers are compared according to the IEEE 754 standard:

• Finite numbers are ordered in the usual manner.
• Positive zero is equal but not greater than negative zero.
• Inf is equal to itself and greater than everything else except `NaN`.
• `-Inf` is equal to itself and less then everything else except `NaN`.
• `NaN` is not equal to, not less than, and not greater than anything, including itself.

The last point is potentially surprising and thus worth noting:

and can cause especial headaches with Arrays:

Julia provides additional functions to test numbers for special values, which can be useful in situations like hash key comparisons:

``````Function      Tests if
isequal(x, y) x and y are identical
isfinite(x)   x is a finite number
isinf(x)      x is infinite
isnan(x)      x is not a number``````

`isequal()` considers `NaN`s equal to each other:

`isequal()` can also be used to distinguish signed zeros:

Mixed-type comparisons between signed integers, unsigned integers, and floats can be tricky. A great deal of care has been taken to ensure that Julia does them correctly.

For other types, `isequal()` defaults to calling `==()`, so if you want to define equality for your own types then you only need to add a `==()` method. If you define your own equality function, you should probably define a corresponding `hash()` method to ensure that `isequal(x,y)` implies `hash(x) == hash(y)`. Anche qui cose che saranno approfondite in futuro.

Concatenare comparazioni
Unlike most languages, with the notable exception of Python, comparisons can be arbitrarily chained:

Chaining comparisons is often quite convenient in numerical code. Chained comparisons use the `&&` operator for scalar comparisons, and the `&` operator for elementwise comparisons, which allows them to work on arrays. For example, `0 .< A .< 1` gives a boolean array whose entries are true where the corresponding elements of `A` are between `0` and `1`.

The middle expression is only evaluated once, rather than twice as it would be if the expression were written as `v(1) < v(2) && v(2) <= v(3)`. However, the order of evaluations in a chained comparison is undefined. It is strongly recommended not to use expressions with side effects (such as printing) in chained comparisons. If side effects are required, the short-circuit `&&` operator should be used explicitly (see Short-Circuit Evaluation [prossimamente]).

Funzioni elementari
Julia provides a comprehensive collection of mathematical functions and operators. These mathematical operations are defined over as broad a class of numerical values as permit sensible definitions, including integers, floating-point numbers, rationals, and complex numbers, wherever such definitions make sense.

Moreover, these functions (like any Julia function) can be applied in “vectorized” fashion to arrays and other collections with the dot syntax `f.(A)`, e.g. `sin.(A)` will compute the sine of each element of an array `A`.

Annunci