Skip to content

Support boolean comparison operations on fields (>, <, >=, <=, ==) #5307

@glwagner

Description

@glwagner

Feature request

Currently, binary operations on fields are limited to arithmetic operators (+, -, *, /, ^). Comparison operators like >, <, >=, <=, == are not supported. It would be useful to support these, returning an AbstractOperation with eltype Bool.

A related issue is that Field(a > b) should produce a Field with eltype Bool (and Bool-valued backing data), rather than the current default of eltype(grid).

MWE (desired behavior)

using Oceananigans

grid = RectilinearGrid(size=(4, 4, 4), extent=(1, 1, 1))

a = CenterField(grid)
b = CenterField(grid)

set!(a, (x, y, z) -> x)
set!(b, (x, y, z) -> 0.5)

# This should work and return a BinaryOperation with eltype Bool
op = a > b
eltype(op)  # should be Bool

# Creating a Field from it should produce Bool-valued data
f = Field(op)
eltype(f)     # should be Bool
compute!(f)
f[1, 1, 1]   # should be false (or true), not 0.0 (or 1.0)

Current behavior

a > b where a and b are fields is not defined and throws a MethodError.

Implementation notes

Two things need to change:

  1. Register comparison operators as binary operations. The @binary macro in src/AbstractOperations/binary_operations.jl could be used to register >, <, >=, <=, ==, though operator precedence / location semantics should be considered.

  2. Derive eltype from the operation, not just the grid. Currently, BinaryOperation, UnaryOperation, and MultiaryOperation all set T = eltype(grid). For comparison operations, T should be Bool. This could be handled by a trait or dispatch on the operator, e.g.:

    result_eltype(op, grid) = eltype(grid)           # default for arithmetic
    result_eltype(::typeof(>), grid) = Bool           # for comparisons

    Similarly, Field construction from a boolean operation should allocate Bool-valued data via something like new_data(Bool, grid, loc, indices).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions