# How to remove branches in Piecewise with measure 0

I am doing Convolve over UnitTriangle in 2 dimensions and the resulting piecewise function has conditions with measure zero (lines or even points). Unfortunately, when plotting, these show up.

Easy to reproduce, here it is

Block[
{k, ak, x, y},
k[x_, y_] := UnitTriangle[x, y];
ak[x_, y_] = Convolve[k[a, b], k[-a, -b], {a, b}, {x, y}];
Print[ak[x, y]];
Plot3D[ak[x, y], {x, -3, 3}, {y, -3, 3}, PlotRange -> All]
]

The output is a big piecewise function definition with conditions such as 1<x<2&&y==0 or x==0&&y==0. The resulting plot then has white lines that, I believe, are artefacts of this.

Question: How can I remove the useless conditions with measure zero in 2D? I am interested not just in fixing the plot but also in simplifying the piecewise definition by deleting useless branches.

Update

Thanks @cvgmt for the Exclusions->None option, it does the trick.

I made some progress in regards to the Piecewise definition. Doing pattern matching to remove ==, which are the cases of measure zero in the branches, and setting those to False reduces the Piecewise definition. This Print[ak[x, y] /. {x == _ | y == _ -> False}]; is much less verbose and produces a compressed definition; but now there are no conditions on the remaining branches as these got converted to <. This is fine for plotting, I bet, but a more sophisticated pattern matching would be nice.

• Are you interested in this particular function, or are you interested in doing this for general piecewise Convolution results? There are two things to reduce the amount of pieces: (a) combine redundant ones (1D and 0D) and (b) rewrite obvious symmetries using common piecewise functions like Abs and Max. (a) is not hard, but (b) is harder in general.
Commented Aug 25, 2022 at 18:00
• @Adam, I am working on a general kernel algorithm that requires also the autocorrelation function for the kernel. My interest in UnitTriangle is to use it as an example. I was curious, anyway, about pattern matching for Piecewise, which I found counter-intuitive. Commented Aug 26, 2022 at 1:44

The raw result is quite strange; it includes pieces like 1/18(-2+x)(1+x)^2(-2+y)^3 defined for x==0,1<y<2; why didn't it already substitute x->0? Don't know, don't care.

Let's use pattern matching to find domains that are nested or adjacent (using your technique of replacing < with <=) and whose equations coincide on the smaller domain:

Convolve[UnitTriangle[a, b], UnitTriangle[-a, -b], {a, b}, {x, y}]
//. {OrderlessPatternSequence[ a___,
{eqn1_, domain1_}, {eqn0_, domain0_}]} /;
And[RegionWithin[ImplicitRegion[domain1 /. Less -> LessEqual, {x, y}],
ImplicitRegion[domain0, {x, y}]],
Simplify[eqn0 == eqn1, Assumptions -> domain0]
] :> {a, {eqn1, domain1 /. Less -> LessEqual}}

This code yields a piecewise function with 16 pieces instead of 49. It's a grid of squares, whose equations may be commensurated if you use Abs; not really sure. The plot still isn't perfect:

but it's an improvement.

We can streamline this a little; if two pieces are equal on the second piece's domain, then the first equation applies on the union of the domains. Likewise, if we can reflect one of the equations and it agrees on the second domain, we can insert an Abs. So

With[{rule = {OrderlessPatternSequence[
a___, {eqn0_, domain0_}, {eqn1_, domain1_}]} /;
Simplify[eqn0 == #@eqn1,
Assumptions -> domain1] :> {a, {#2@eqn0,
Simplify[domain0 \[Or] domain1]}} &},
Convolve[UnitTriangle[a, b], UnitTriangle[-a, -b], {a, b}, {x, y}]
//. {rule[# &, # &],
rule[# /. x -> -x &, # /. x -> Abs@x &],
rule[# /. y -> -y &, # /. y -> Abs@y &]}]

yields a function with only four pieces. These can probably be combined further with smart combinations involving Max[x,y].

In response to OP's clarification about the purpose of this question:

First, my replacing x->Abs@x should have an extra condition that checks which symmetric half is the positive one and which one is negative; I just got lucky.

Second, a major improvement to my answer would be to speed up the //. dramatically by perhaps evaluating the pieces on random rational inputs so that distinct pairs may be weeded out immediately or by caching simplifications somehow or restricting the functions available to Simplify.

Third, a different avenue to remove redundancies in the Piecewise might be to attempt to rewrite it involving nested Piecewise functions, with an end goal of having every nested Piecewise converted to an Abs or other 'atomic' component (this particular one might be a function of only Abs[x-y] and Abs[x+y]). Along these lines, maybe the whole thing, as a sum of expressions times indicator functions, may have algebra done on it (a polynomial involving UnitSteps)

• Thanks Adam. The plot can be fixed as per @cvgmt's answer, but that was not my main concern. My end goal (and I should have said this from start) is to use this piecewise definition in other software. My simplistic approach was getting ak[0,0] => 0 but yours give the correct answer 4/9. I was afraid because of the risk of having boundary values like these being wrongly calculated without knowing. Side note: a branch like x==0 has measure 0 in theory, but not on a computer with limited precision. Again, thanks. Commented Aug 25, 2022 at 3:00
• @carlosayam my edit should be valid without assumptions on the boundaries.
Commented Aug 25, 2022 at 3:01
• Just saw it, great. I was not able to get the pattern matching to work: the definition uses Less[a_, x, b_] rather than And[Less[a_,x],Less[x,a_]]. I will study your matching strategy in detail: something new to learn. Commented Aug 25, 2022 at 3:04

Edit

• Another way is use the defination of Convolve. Here we use NIntegrate instead of Integrate.
Clear[k,l,bk];
k[x_, y_] = UnitTriangle[x, y];
l[x_, y_] = k[-x, -y];
(* ak[x_,y_]=Convolve[k[a,b],l[a,b],{a,b},{x,y}]; *)
bk[x_, y_] :=
NIntegrate[
k[a, b] l[x - a,
y - b], {a, -∞, ∞}, {b, -∞, ∞}]
Plot3D[bk[x, y], {x, -3, 3}, {y, -3, 3}, PlotRange -> All]
• SetExclusions->None.
Plot3D[ak[x, y], {x, -3, 3}, {y, -3, 3}, PlotRange -> All,   Exclusions -> None]

• Thank you, that does the trick for having a smooth plot. But how can I remove those branches in the piecewise definition resulting from Convolve that define lines and points? The autocorrelation is a continuous function and those are irrelevant. Commented Aug 24, 2022 at 12:01