Making a Boolean Operator Not a Boolean Operator (And Operator Precedence)

I’ve defined the binary “parallel” operator as:

∥(a::Number,b::Number) = 1/(1/a+1/b)

This operation is very common in electronics, and is related to the harmonic mean.

I’ve also overloaded it with ∥(a::Component,b::Component) to allow the paralleling of a custom data structure I created.

It works very well (although of course I’d prefer to type \par instead of \parallel, but I’ll save that for later)…

julia> 1 ∥ 2
0.6666666666666666

However, if I try cascading it, it doesn’t work so well.

julia> 1 ∥ 2 ∥ 3
TypeError: non-boolean (Float64) used in boolean context

Stacktrace:
 [1] top-level scope at In[48]:1
 [2] include_string(::Function, ::Module, ::String, ::String) at .\loading.jl:1091

I found from this link that the problem is that Julia expects this operator to return a Boolean and performs conditional evaluation.

julia> Meta.@lower 1 ∥ 2 ∥ 3
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope'
1 ─ %1 = 1 ∥ 2
└──      goto #3 if not %1
2 ─ %3 = 2 ∥ 3
└──      return %3
3 ─      return false
))))
  1. Can I disable this Boolean treatment somehow? (Without custom macros)
  2. How can I set its operator precedence to the same as +? (Since ∥ and + share the same arithmetic properties.)

Thanks!

Re (2), you can’t - see Matt’s comment here and the linked post from Stefan here: On adjoints and custom postfix and infix operators - #61 by StefanKarpinski

2 Likes

Okay, I think I’ve found a solution. :wink:

Instead of overloading the parallel operator \parallel to return something non-Boolean, I’ve realized that the notation I seek exists so I’ve chosen to call my harmonic sum +_p where p=-1.

This is similar to the notation for S_p sum of powers, L_p norms, and M_p power means, in which cases p is used to signify the power that the arguments are raised to before performing the summing function. They’re defined as:

S_p(x_1,\ldots,x_n)=\sum_{i=1}^nx_i^p,

L_p(x_1, \ldots, x_n) = \left(\sum_{i=1}^n |x_i|^p\right)^{1/p}, and

M_p(x_1, \ldots, x_n) = \left(\frac{1}{n}\sum_{i=1}^n x_i^p\right)^{1/p}.

Similarly I can define

a+_pb=(a^p+b^p)^{1/p},

which is similar to the S_p sum of powers (but taking the result to the 1/p), the L_p norm (but without taking the absolute power), and the M_p mean (but without dividing by n^{1/p}). They could be related as:

S_p(x_1,\ldots,x_n)=(x_1+_p\ldots+_px_n)^p,

L_p(x_1,\ldots,x_n)=(|x_1|+_p\ldots+_p|x_n|), and

M_p(x_1,\ldots,x_n)=\left(\frac{1}{n}\right)^{1/p}(x_1+_p\ldots+_px_n).

For example, the quadratic sum of a and b is a+_2 b = L_2(a,b), and for my harmonic sum I can write:

+₋₁(a::Number,b::Number) = 1/(1/a+1/b)

(Super yay for allowing Unicode characters in operator names! :smiley::smiley::smiley:)

Fun sidenote, the distributive property a(b+_pc)=ab+_pac holds for any p\ne 0.

To incorporate the implicit meaning of a harmonic sum where two rates add in harmony, I can refer to +_{-1} as simply +_h. So,

+ₕ(a::Number,b::Number) = 1/(1/a+1/b)

This notation is consistent with that for the Kolmogorov-Nagumo generalized f-mean M_f, which is defined for some continuous monotone function f as:

M_f(x_1,\ldots,x_n)=f^{-1}\left(\frac{1}{n}\sum_{i=1}^nf(x_i)\right).

I can write a generalized f-sum as

a+_fb = f^{-1}(f(a)+f(b)).

M_h is the harmonic mean where h(x)=x^{-1}, and with my notation, +_h is the harmonic sum. Similarly, M_q is the quadratic mean and +_q is the quadratic sum where q(x)=x^2.

1 Like