Matrix Conditional Assignment
In MATLAB, it is fairly simple to assign to a subset of a matrix, for example, the values that satisfy a given condition. For example, saturation can be obtained as follows:
A[A < 0] = 0
A[A > 1] = 1
In Quasar, this can be achieved with:
A = saturate(A)
However, the situation can be more complex and then there is no direct equivalent to MATLAB. For example,
A[A > B] = C
where A
, B
, C
are all matrices. The trick is to define a reduction (now in system.q
):
type matrix_type : [vec|mat|cube|cvec|cmat|ccube]
reduction (x : matrix_type, a : matrix_type, b, c) -> (x[a > b] = c) = (x += (c - x) .* (a > b))
reduction (x : matrix_type, a : matrix_type, b, c) -> (x[a < b] = c) = (x += (c - x) .* (a < b))
reduction (x : matrix_type, a : matrix_type, b, c) -> (x[a <= b] = c) = (x += (c - x) .* (a <= b))
reduction (x : matrix_type, a : matrix_type, b, c) -> (x[a >= b] = c) = (x += (c - x) .* (a >= b))
reduction (x : matrix_type, a : matrix_type, b, c) -> (x[a == b] = c) = (x += (c - x) .* (a == b))
reduction (x : matrix_type, a : matrix_type, b, c) -> (x[a != b] = c) = (x += (c - x) .* (a != b))
reduction (x : matrix_type, a : matrix_type, b, c) -> (x[a && b] = c) = (x += (c - x) .* (a && b))
reduction (x : matrix_type, a : matrix_type, b, c) -> (x[a || b] = c) = (x += (c - x) .* (a || b))
The first line defines a “general” matrix type, then is then used for the subsequent reductions. The reduction simply works on patterns of the form:
x[a #op# b] = c
and replaces them by the appropriate Quasar expression. The last two reductions are a trick, to get the conditional assignment also working with boolean expressions, such as:
A[A<-0.1 || A>0.1] = 5
Note that, on the other hand:
B = A[A<-0.1]
will currently result in a runtime error (this syntax is not defined yet).