ArrayOperations
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © RicardoSantos

//@version=5

// @description Array Basic Operations. 
library(title='ArrayOperations')

import RicardoSantos/MathExtension/1 as me
import RicardoSantos/ArrayExtension/3 as ae
import RicardoSantos/DebugConsole/6 as console
[__T, __C] = console.init(25)

// Helper method for add() process.
add_method (sample_a, sample_b) => //{
    int _size_a = array.size(id=sample_a)
    int _size_b = array.size(id=sample_b)
    //
    switch
        (_size_a < 1) => runtime.error('ArrayOperations -> add(): "_size_a" is invalid')
        (_size_b < 1) => runtime.error('ArrayOperations -> add(): "_size_b" is invalid')
        (_size_a < _size_b) => runtime.error('ArrayOperations -> add(): "_size_b" must be smaller or equal to _size_a')
    //
    _output = array.copy(sample_a)// defines output type
    for _i = 0 to _size_a - 1
        _ai = array.get(id=sample_a, index=_i)
        _bi = array.get(id=sample_b, index=_i % _size_b)
        array.set(id=_output, index=_i, value=_ai + _bi)
    _output
//
// @function Adds sample_b to sample_a and returns a new array.
// @param sample_a values to be added to.
// @param sample_b values to add.
// @returns array with added results.
//      -sample_a provides type format for output.
//      -arrays do not need to be symmetric.
//      -sample_a must have same or more elements than sample_b
export add(float[] sample_a, float[] sample_b) => add_method(sample_a, sample_b)
export add(float[] sample_a, int[] sample_b) => add_method(sample_a, ae.to_float(sample_b))
export add(int[] sample_a, int[] sample_b) => add_method(sample_a, sample_b)
export add(string[] sample_a, string[] sample_b) => add_method(sample_a, sample_b)
//{ usage:
console.queue_one(__C, str.format('add(): {0}', add(array.from(0, 1, 2), array.from(3, 4, 5))))
// console.queue_one(__C, str.format('add(): {0}', add(array.from(0.1, 1.1, 2.1), array.from(3, 4, 5))))
// console.queue_one(__C, str.format('add(): {0}', add(array.from('a', 'b', 'c'), array.from('3', '4'))))
//}}

// Helper method for subtract() process.
subtract_method (sample_a, sample_b) => //{
    int _size_a = array.size(id=sample_a)
    int _size_b = array.size(id=sample_b)
    //
    switch
        (_size_a < 1) => runtime.error('ArrayOperations -> subtract(): "_size_a" is invalid')
        (_size_b < 1) => runtime.error('ArrayOperations -> subtract(): "_size_b" is invalid')
        (_size_a < _size_b) => runtime.error('ArrayOperations -> subtract(): "_size_b" must be smaller or equal to _size_a')
    //
    _output = array.copy(sample_a)// defines output type
    for _i = 0 to _size_a - 1
        _ai = array.get(id=sample_a, index=_i)
        _bi = array.get(id=sample_b, index=_i % _size_b)
        array.set(id=_output, index=_i, value=_ai - _bi)
    _output
//
// @function Subtracts sample_b from sample_a and returns a new array.
// @param sample_a values to be subtracted from.
// @param sample_b values to subtract.
// @returns array with subtracted results.
//      -sample_a provides type format for output.
//      -arrays do not need to be symmetric.
//      -sample_a must have same or more elements than sample_b
export subtract(float[] sample_a, float[] sample_b) => subtract_method(sample_a, sample_b)
export subtract(float[] sample_a, int[] sample_b) => subtract_method(sample_a, ae.to_float(sample_b))
export subtract(int[] sample_a, int[] sample_b) => subtract_method(sample_a, sample_b)
//{ usage:
console.queue_one(__C, str.format('subtract(): {0}', subtract(array.from(0, 1, 2), array.from(3, 4, 5))))
// console.queue_one(__C, str.format('subtract(): {0}', subtract(array.from(1.1, 2.2, 3.3), array.from(4, 5))))
//}}

// Helper method for multiply() process.
multiply_method (sample_a, sample_b) => //{
    int _size_a = array.size(id=sample_a)
    int _size_b = array.size(id=sample_b)
    //
    switch
        (_size_a < 1) => runtime.error('ArrayOperations -> multiply(): "_size_a" is invalid')
        (_size_b < 1) => runtime.error('ArrayOperations -> multiply(): "_size_b" is invalid')
        (_size_a < _size_b) => runtime.error('ArrayOperations -> multiply(): "_size_b" must be smaller or equal to _size_a')
    //
    _output = array.copy(sample_a)// defines output type
    for _i = 0 to _size_a - 1
        _ai = array.get(id=sample_a, index=_i)
        _bi = array.get(id=sample_b, index=_i % _size_b)
        array.set(id=_output, index=_i, value=_ai * _bi)
    _output
//
// @function multiply sample_a by sample_b and returns a new array.
// @param sample_a values to multiply.
// @param sample_b values to multiply with.
// @returns array with multiplied results.
//      -sample_a provides type format for output.
//      -arrays do not need to be symmetric.
//      -sample_a must have same or more elements than sample_b
export multiply(float[] sample_a, float[] sample_b) => multiply_method(sample_a, sample_b)
export multiply(float[] sample_a, int[] sample_b) => multiply_method(sample_a, ae.to_float(sample_b))
export multiply(int[] sample_a, int[] sample_b) => multiply_method(sample_a, sample_b)
//{ usage:
console.queue_one(__C, str.format('multiply(): {0}', multiply(array.from(0, 1, 2), array.from(3, 4, 5))))
// console.queue_one(__C, str.format('multiply(): {0}', multiply(array.from(1.1, 2.2, 3.3), array.from(4, 5))))
//}}

// Helper method for divide() process.
divide_method (sample_a, sample_b) => //{
    int _size_a = array.size(id=sample_a)
    int _size_b = array.size(id=sample_b)
    //
    switch
        (_size_a < 1) => runtime.error('ArrayOperations -> divide(): "_size_a" is invalid')
        (_size_b < 1) => runtime.error('ArrayOperations -> divide(): "_size_b" is invalid')
        (_size_a < _size_b) => runtime.error('ArrayOperations -> divide(): "_size_b" must be smaller or equal to _size_a')
    //
    _output = array.copy(sample_a)// defines output type
    for _i = 0 to _size_a - 1
        _ai = array.get(id=sample_a, index=_i)
        _bi = array.get(id=sample_b, index=_i % _size_b)
        array.set(id=_output, index=_i, value=_ai / _bi)
    _output
//
// @function Divide sample_a by sample_b and returns a new array.
// @param sample_a values to divide.
// @param sample_b values to divide with.
// @returns array with divided results.
//      -sample_a provides type format for output.
//      -arrays do not need to be symmetric.
//      -sample_a must have same or more elements than sample_b
export divide(float[] sample_a, float[] sample_b) => divide_method(sample_a, sample_b)
export divide(float[] sample_a, int[] sample_b) => divide_method(sample_a, ae.to_float(sample_b))
export divide(int[] sample_a, int[] sample_b) => divide_method(sample_a, sample_b)
//{ usage:
console.queue_one(__C, str.format('divide(): {0}', divide(array.from(0, 8, 15), array.from(3, 4, 5))))
// console.queue_one(__C, str.format('divide(): {0}', divide(array.from(1.1, 2.2, 3.3), array.from(4, 5))))
//}}

// Helper method for power() process.
power_method (sample_a, sample_b) => //{
    int _size_a = array.size(id=sample_a)
    int _size_b = array.size(id=sample_b)
    //
    switch
        (_size_a < 1) => runtime.error('ArrayOperations -> power(): "_size_a" is invalid')
        (_size_b < 1) => runtime.error('ArrayOperations -> power(): "_size_b" is invalid')
        (_size_a < _size_b) => runtime.error('ArrayOperations -> power(): "_size_b" must be smaller or equal to _size_a')
    //
    float[] _output = array.new_float(_size_a)
    for _i = 0 to _size_a - 1
        _ai = array.get(id=sample_a, index=_i)
        _bi = array.get(id=sample_b, index=_i % _size_b)
        array.set(id=_output, index=_i, value=math.pow(_ai, _bi))
    _output
//
// @function power sample_a by sample_b and returns a new array.
// @param sample_a values to power.
// @param sample_b values to power with.
// @returns float array with power results.
//      -sample_a provides type format for output.
//      -arrays do not need to be symmetric.
//      -sample_a must have same or more elements than sample_b
export power(float[] sample_a, float[] sample_b) => power_method(sample_a, sample_b)
export power(float[] sample_a, int[] sample_b) => power_method(sample_a, sample_b)
export power(int[] sample_a, int[] sample_b) => power_method(sample_a, sample_b)
export power(int[] sample_a, float[] sample_b) => power_method(sample_a, sample_b)
//{ usage:
console.queue_one(__C, str.format('power(): {0}', power(array.from(0, 8, 15), array.from(3, 4, 5))))
// console.queue_one(__C, str.format('power(): {0}', power(array.from(1.1, 2.2, 3.3), array.from(4, 5))))
//}}

// Helper method for log() process.
log_method (sample_a) => //{
    int _size_a = array.size(id=sample_a)
    //
    switch
        (_size_a < 1) => runtime.error('ArrayOperations -> power(): "_size_a" is invalid')
    //
    float[] _output = array.new_float(_size_a)
    for _i = 0 to _size_a - 1
        _ai = array.get(id=sample_a, index=_i)
        array.set(id=_output, index=_i, value=math.log(_ai))
    _output
//
// @function power sample_a by sample_b and returns a new array.
// @param sample_a values to power.
// @returns float array with log results.
export log(float[] sample_a) => log_method(sample_a)
export log(int[] sample_a) => log_method(sample_a)
//{ usage:
console.queue_one(__C, str.format('log(): {0}', log(array.from(0, 8, 15))))
//}}

// Helper method for remainder() process.
remainder_method (sample_a, sample_b) => //{
    int _size_a = array.size(id=sample_a)
    int _size_b = array.size(id=sample_b)
    //
    switch
        (_size_a < 1) => runtime.error('ArrayOperations -> remainder(): "_size_a" is invalid')
        (_size_b < 1) => runtime.error('ArrayOperations -> remainder(): "_size_b" is invalid')
        (_size_a < _size_b) => runtime.error('ArrayOperations -> remainder(): "_size_b" must be smaller or equal to _size_a')
    //
    _output = array.copy(sample_a)
    for _i = 0 to _size_a - 1
        _ai = array.get(id=sample_a, index=_i)
        _bi = array.get(id=sample_b, index=_i % _size_b)
        array.set(id=_output, index=_i, value=me.fmod(_ai, _bi))
    _output
//
// @function Remainder sample_a by sample_b and returns a new array.
// @param sample_a values to remainder.
// @param sample_b values to remainder with.
// @returns array with remainder results.
//      -sample_a provides type format for output.
//      -arrays do not need to be symmetric.
//      -sample_a must have same or more elements than sample_b
export remainder(float[] sample_a, float[] sample_b) => remainder_method(sample_a, sample_b)
export remainder(float[] sample_a, int[] sample_b) => remainder_method(sample_a, ae.to_float(sample_b))
export remainder(int[] sample_a, int[] sample_b) => remainder_method(ae.to_float(sample_a), ae.to_float(sample_b))
export remainder(int[] sample_a, float[] sample_b) => remainder_method(ae.to_float(sample_a), sample_b)
//{ usage:
console.queue_one(__C, str.format('remainder(): {0}', remainder(array.from(0, 5, 22), array.from(3.0, 4.5, 5))))
// console.queue_one(__C, str.format('remainder(): {0}', remainder(array.from(1.1, 2.2, 3.3), array.from(4, 5))))
//}}

// Helper method for equal() process.
equal_method (sample_a, sample_b) => //{
    int _size_a = array.size(id=sample_a)
    int _size_b = array.size(id=sample_b)
    //
    switch
        (_size_a < 1) => runtime.error('ArrayOperations -> equal(): "_size_a" is invalid')
        (_size_b < 1) => runtime.error('ArrayOperations -> equal(): "_size_b" is invalid')
        (_size_a < _size_b) => runtime.error('ArrayOperations -> equal(): "_size_b" must be smaller or equal to _size_a')
    //
    int[] _output = array.new_int(_size_a, 0)
    for _i = 0 to _size_a - 1
        _ai = array.get(id=sample_a, index=_i)
        _bi = array.get(id=sample_b, index=_i % _size_b)
        array.set(id=_output, index=_i, value=_ai == _bi ? 1 : 0)
    _output
//
// @function Check element wise sample_a equals sample_b and returns a new array.
// @param sample_a values to check.
// @param sample_b values to check.
// @returns int array with results.
//      -sample_a provides type format for output.
//      -arrays do not need to be symmetric.
//      -sample_a must have same or more elements than sample_b
export equal(float[] sample_a, float[] sample_b) => equal_method(sample_a, sample_b)
export equal(float[] sample_a, int[] sample_b) => equal_method(sample_a, ae.to_float(sample_b))
export equal(int[] sample_a, int[] sample_b) => equal_method(sample_a, sample_b)
export equal(int[] sample_a, float[] sample_b) => equal_method(ae.to_float(sample_a), sample_b)
export equal(string[] sample_a, string[] sample_b) => equal_method(sample_a, sample_b)
export equal(color[] sample_a, color[] sample_b) => equal_method(sample_a, sample_b)
//{ usage:
console.queue_one(__C, str.format('equal(): {0}', equal(array.from(0, 5), array.from(0.0, 4))))
// console.queue_one(__C, str.format('equal(): {0}', equal(array.from('1.1', 'a', 'b'), array.from('2.2', 'a'))))
// console.queue_one(__C, str.format('equal(): {0}', equal(array.from(color.red, color.blue), array.from(color.red))))
//}}

// Helper method for not_equal() process.
not_equal_method (sample_a, sample_b) => //{
    int _size_a = array.size(id=sample_a)
    int _size_b = array.size(id=sample_b)
    //
    switch
        (_size_a < 1) => runtime.error('ArrayOperations -> not_equal(): "_size_a" is invalid')
        (_size_b < 1) => runtime.error('ArrayOperations -> not_equal(): "_size_b" is invalid')
        (_size_a < _size_b) => runtime.error('ArrayOperations -> not_equal(): "_size_b" must be smaller or equal to _size_a')
    //
    int[] _output = array.new_int(_size_a, 0)
    for _i = 0 to _size_a - 1
        _ai = array.get(id=sample_a, index=_i)
        _bi = array.get(id=sample_b, index=_i % _size_b)
        array.set(id=_output, index=_i, value=_ai != _bi ? 1 : 0)
    _output
//
// @function Check element wise sample_a not equals sample_b and returns a new array.
// @param sample_a values to check.
// @param sample_b values to check.
// @returns int array with results.
//      -sample_a provides type format for output.
//      -arrays do not need to be symmetric.
//      -sample_a must have same or more elements than sample_b
export not_equal(float[] sample_a, float[] sample_b) => not_equal_method(sample_a, sample_b)
export not_equal(float[] sample_a, int[] sample_b) => not_equal_method(sample_a, ae.to_float(sample_b))
export not_equal(int[] sample_a, int[] sample_b) => not_equal_method(sample_a, sample_b)
export not_equal(int[] sample_a, float[] sample_b) => not_equal_method(ae.to_float(sample_a), sample_b)
export not_equal(string[] sample_a, string[] sample_b) => not_equal_method(sample_a, sample_b)
export not_equal(color[] sample_a, color[] sample_b) => not_equal_method(sample_a, sample_b)
//{ usage:
// console.queue_one(__C, str.format('not_equal(): {0}', not_equal(array.from(0, 5), array.from(0.0, 4))))
// console.queue_one(__C, str.format('not_equal(): {0}', not_equal(array.from('1.1', 'a', 'b'), array.from('2.2', 'a'))))
console.queue_one(__C, str.format('not_equal(): {0}', not_equal(array.from(color.red, color.blue), array.from(color.red))))
//}}

// Helper method for over_or_equal() process.
over_or_equal_method (sample_a, sample_b) => //{
    int _size_a = array.size(id=sample_a)
    int _size_b = array.size(id=sample_b)
    //
    switch
        (_size_a < 1) => runtime.error('ArrayOperations -> over_or_equal(): "_size_a" is invalid')
        (_size_b < 1) => runtime.error('ArrayOperations -> over_or_equal(): "_size_b" is invalid')
        (_size_a < _size_b) => runtime.error('ArrayOperations -> over_or_equal(): "_size_b" must be smaller or equal to _size_a')
    //
    int[] _output = array.new_int(_size_a, 0)
    for _i = 0 to _size_a - 1
        _ai = array.get(id=sample_a, index=_i)
        _bi = array.get(id=sample_b, index=_i % _size_b)
        array.set(id=_output, index=_i, value=_ai >= _bi ? 1 : 0)
    _output
//
// @function Check element wise sample_a over or equals sample_b and returns a new array.
// @param sample_a values to check.
// @param sample_b values to check.
// @returns int array with results.
//      -sample_a provides type format for output.
//      -arrays do not need to be symmetric.
//      -sample_a must have same or more elements than sample_b
export over_or_equal(float[] sample_a, float[] sample_b) => over_or_equal_method(sample_a, sample_b)
export over_or_equal(float[] sample_a, int[] sample_b) => over_or_equal_method(sample_a, ae.to_float(sample_b))
export over_or_equal(int[] sample_a, int[] sample_b) => over_or_equal_method(sample_a, sample_b)
export over_or_equal(int[] sample_a, float[] sample_b) => over_or_equal_method(ae.to_float(sample_a), sample_b)
//{ usage:
console.queue_one(__C, str.format('over_or_equal(): {0}', over_or_equal(array.from(0, 5, 3), array.from(0.0, 4, 6))))
//}}

// Helper method for under_or_equal() process.
under_or_equal_method (sample_a, sample_b) => //{
    int _size_a = array.size(id=sample_a)
    int _size_b = array.size(id=sample_b)
    //
    switch
        (_size_a < 1) => runtime.error('ArrayOperations -> under_or_equal(): "_size_a" is invalid')
        (_size_b < 1) => runtime.error('ArrayOperations -> under_or_equal(): "_size_b" is invalid')
        (_size_a < _size_b) => runtime.error('ArrayOperations -> under_or_equal(): "_size_b" must be smaller or equal to _size_a')
    //
    int[] _output = array.new_int(_size_a, 0)
    for _i = 0 to _size_a - 1
        _ai = array.get(id=sample_a, index=_i)
        _bi = array.get(id=sample_b, index=_i % _size_b)
        array.set(id=_output, index=_i, value=_ai <= _bi ? 1 : 0)
    _output
//
// @function Check element wise sample_a under or equals sample_b and returns a new array.
// @param sample_a values to check.
// @param sample_b values to check.
// @returns int array with results.
//      -sample_a provides type format for output.
//      -arrays do not need to be symmetric.
//      -sample_a must have same or more elements than sample_b
export under_or_equal(float[] sample_a, float[] sample_b) => under_or_equal_method(sample_a, sample_b)
export under_or_equal(float[] sample_a, int[] sample_b) => under_or_equal_method(sample_a, ae.to_float(sample_b))
export under_or_equal(int[] sample_a, int[] sample_b) => under_or_equal_method(sample_a, sample_b)
export under_or_equal(int[] sample_a, float[] sample_b) => under_or_equal_method(ae.to_float(sample_a), sample_b)
//{ usage:
console.queue_one(__C, str.format('under_or_equal(): {0}', under_or_equal(array.from(0, 5, 3), array.from(0.0, 4, 6))))
//}}

// Helper method for over() process.
over_method (sample_a, sample_b) => //{
    int _size_a = array.size(id=sample_a)
    int _size_b = array.size(id=sample_b)
    //
    switch
        (_size_a < 1) => runtime.error('ArrayOperations -> over(): "_size_a" is invalid')
        (_size_b < 1) => runtime.error('ArrayOperations -> over(): "_size_b" is invalid')
        (_size_a < _size_b) => runtime.error('ArrayOperations -> over(): "_size_b" must be smaller or equal to _size_a')
    //
    int[] _output = array.new_int(_size_a, 0)
    for _i = 0 to _size_a - 1
        _ai = array.get(id=sample_a, index=_i)
        _bi = array.get(id=sample_b, index=_i % _size_b)
        array.set(id=_output, index=_i, value=_ai > _bi ? 1 : 0)
    _output
//
// @function Check element wise sample_a over sample_b and returns a new array.
// @param sample_a values to check.
// @param sample_b values to check.
// @returns int array with results.
//      -sample_a provides type format for output.
//      -arrays do not need to be symmetric.
//      -sample_a must have same or more elements than sample_b
export over(float[] sample_a, float[] sample_b) => over_method(sample_a, sample_b)
export over(float[] sample_a, int[] sample_b) => over_method(sample_a, ae.to_float(sample_b))
export over(int[] sample_a, int[] sample_b) => over_method(sample_a, sample_b)
export over(int[] sample_a, float[] sample_b) => over_method(ae.to_float(sample_a), sample_b)
//{ usage:
console.queue_one(__C, str.format('over(): {0}', over(array.from(0, 5, 3), array.from(0.0, 4, 6))))
//}}

// Helper method for under() process.
under_method (sample_a, sample_b) => //{
    int _size_a = array.size(id=sample_a)
    int _size_b = array.size(id=sample_b)
    //
    switch
        (_size_a < 1) => runtime.error('ArrayOperations -> under(): "_size_a" is invalid')
        (_size_b < 1) => runtime.error('ArrayOperations -> under(): "_size_b" is invalid')
        (_size_a < _size_b) => runtime.error('ArrayOperations -> under(): "_size_b" must be smaller or equal to _size_a')
    //
    int[] _output = array.new_int(_size_a, 0)
    for _i = 0 to _size_a - 1
        _ai = array.get(id=sample_a, index=_i)
        _bi = array.get(id=sample_b, index=_i % _size_b)
        array.set(id=_output, index=_i, value=_ai < _bi ? 1 : 0)
    _output
//
// @function Check element wise sample_a under sample_b and returns a new array.
// @param sample_a values to check.
// @param sample_b values to check.
// @returns int array with results.
//      -sample_a provides type format for output.
//      -arrays do not need to be symmetric.
//      -sample_a must have same or more elements than sample_b
export under(float[] sample_a, float[] sample_b) => under_method(sample_a, sample_b)
export under(float[] sample_a, int[] sample_b) => under_method(sample_a, ae.to_float(sample_b))
export under(int[] sample_a, int[] sample_b) => under_method(sample_a, sample_b)
export under(int[] sample_a, float[] sample_b) => under_method(ae.to_float(sample_a), sample_b)
//{ usage:
console.queue_one(__C, str.format('under(): {0}', under(array.from(0, 5, 3), array.from(0.0, 4, 6))))
//}}

// Helper method for and_() process.
and_method (sample_a, sample_b) => //{
    int _size_a = array.size(id=sample_a)
    int _size_b = array.size(id=sample_b)
    //
    switch
        (_size_a < 1) => runtime.error('ArrayOperations -> and_(): "_size_a" is invalid')
        (_size_b < 1) => runtime.error('ArrayOperations -> and_(): "_size_b" is invalid')
        (_size_a < _size_b) => runtime.error('ArrayOperations -> and_(): "_size_b" must be smaller or equal to _size_a')
    //
    int[] _output = array.new_int(_size_a, 0)
    for _i = 0 to _size_a - 1
        _ai = array.get(id=sample_a, index=_i)
        _bi = array.get(id=sample_b, index=_i % _size_b)
        array.set(id=_output, index=_i, value=(_ai > 0) and (_bi > 0) ? 1 : 0)
    _output
//
// @function Check element wise sample_a and sample_b and returns a new array.
// @param sample_a values to check.
// @param sample_b values to check.
// @returns int array with results.
//      -sample_a provides type format for output.
//      -arrays do not need to be symmetric.
//      -sample_a must have same or more elements than sample_b
export and_(float[] sample_a, float[] sample_b) => and_method(sample_a, sample_b)
export and_(float[] sample_a, int[] sample_b) => and_method(sample_a, ae.to_float(sample_b))
export and_(float[] sample_a, bool[] sample_b) => and_method(sample_a, ae.to_float(sample_b))
export and_(int[] sample_a, int[] sample_b) => and_method(sample_a, sample_b)
export and_(int[] sample_a, float[] sample_b) => and_method(ae.to_float(sample_a), sample_b)
export and_(int[] sample_a, bool[] sample_b) => and_method(sample_a, ae.to_float(sample_b))
export and_(bool[] sample_a, bool[] sample_b) => and_method(ae.to_float(sample_a), ae.to_float(sample_b))
export and_(bool[] sample_a, int[] sample_b) => and_method(ae.to_float(sample_a), ae.to_float(sample_b))
export and_(bool[] sample_a, float[] sample_b) => and_method(ae.to_float(sample_a), sample_b)
//{ usage:
console.queue_one(__C, str.format('and_(): {0}', and_(array.from(0, 5, 3), array.from(0.0, 4, 0))))
//}}

// Helper method for or_() process.
or_method (sample_a, sample_b) => //{
    int _size_a = array.size(id=sample_a)
    int _size_b = array.size(id=sample_b)
    //
    switch
        (_size_a < 1) => runtime.error('ArrayOperations -> or_(): "_size_a" is invalid')
        (_size_b < 1) => runtime.error('ArrayOperations -> or_(): "_size_b" is invalid')
        (_size_a < _size_b) => runtime.error('ArrayOperations -> or_(): "_size_b" must be smaller or equal to _size_a')
    //
    int[] _output = array.new_int(_size_a, 0)
    for _i = 0 to _size_a - 1
        _ai = array.get(id=sample_a, index=_i)
        _bi = array.get(id=sample_b, index=_i % _size_b)
        array.set(id=_output, index=_i, value=(_ai > 0) or (_bi > 0) ? 1 : 0)
    _output
//
// @function Check element wise sample_a or sample_b and returns a new array.
// @param sample_a values to check.
// @param sample_b values to check.
// @returns int array with results.
//      -sample_a provides type format for output.
//      -arrays do not need to be symmetric.
//      -sample_a must have same or more elements than sample_b
export or_(float[] sample_a, float[] sample_b) => or_method(sample_a, sample_b)
export or_(float[] sample_a, int[] sample_b) => or_method(sample_a, ae.to_float(sample_b))
export or_(float[] sample_a, bool[] sample_b) => or_method(sample_a, ae.to_float(sample_b))
export or_(int[] sample_a, int[] sample_b) => or_method(sample_a, sample_b)
export or_(int[] sample_a, float[] sample_b) => or_method(ae.to_float(sample_a), sample_b)
export or_(int[] sample_a, bool[] sample_b) => or_method(sample_a, ae.to_float(sample_b))
export or_(bool[] sample_a, bool[] sample_b) => or_method(ae.to_float(sample_a), ae.to_float(sample_b))
export or_(bool[] sample_a, int[] sample_b) => or_method(ae.to_float(sample_a), ae.to_float(sample_b))
export or_(bool[] sample_a, float[] sample_b) => or_method(ae.to_float(sample_a), sample_b)
//{ usage:
console.queue_one(__C, str.format('or_(): {0}', or_(array.from(0, 5, 3), array.from(0.0, 4, 0))))
//}}

// Helper method for all() process.
all_method (sample) => //{
    int _size = array.size(id=sample)
    //
    switch
        (_size < 1) => runtime.error('ArrayOperations -> all(): "_size_a" is invalid')
    //
    int _output = 1
    for _i = 0 to _size - 1
        _ai = array.get(id=sample, index=_i)
        if (_ai > 0)
            continue
        else
            _output := 0
            break
    _output
//
// @function Check element wise if all numeric samples are true (!= 0).
// @param sample_a values to check.
// @returns int array with results.
//      -sample_a provides type format for output.
//      -arrays do not need to be symmetric.
//      -sample_a must have same or more elements than sample_b
export all(float[] sample) => all_method(sample)
export all(int[] sample) => all_method(sample)
export all(bool[] sample) => all_method(ae.to_int(sample))
//{ usage:
console.queue_one(__C, str.format('all(): {0}', all(array.from(0, 5, 3))))
console.queue_one(__C, str.format('all(): {0}', all(array.from(0.2, 1))))
//}}

// Helper method for any() process.
any_method (sample) => //{
    int _size = array.size(id=sample)
    //
    switch
        (_size < 1) => runtime.error('ArrayOperations -> any(): "_size_a" is invalid')
    //
    int _output = 0
    for _i = 0 to _size - 1
        _ai = array.get(id=sample, index=_i)
        if (_ai > 0)
            _output := 1
            break
        else
            continue
    _output
//
// @function Check element wise if any numeric samples are true (!= 0).
// @param sample_a values to check.
// @returns int array with results.
//      -sample_a provides type format for output.
//      -arrays do not need to be symmetric.
//      -sample_a must have same or more elements than sample_b
export any(float[] sample) => any_method(sample)
export any(int[] sample) => any_method(sample)
export any(bool[] sample) => any_method(ae.to_int(sample))
//{ usage:
console.queue_one(__C, str.format('any(): {0}', any(array.from(0, 5, 3))))
console.queue_one(__C, str.format('any(): {0}', any(array.from(0., -1))))
//}}


console.update(__T, __C)