# programmable filter gives wrong results

**URL:** https://discourse.paraview.org/t/programmable-filter-gives-wrong-results/12492
**Category:** ParaView Support
**Created:** [July 11, 2023, 9:38am UTC](https://discourse.paraview.org/t/programmable-filter-gives-wrong-results/12492 "2023-07-11T09:38:55Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![simonw](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@simonw](https://discourse.paraview.org/u/simonw)
#### Post date: [July 11, 2023, 9:38am UTC](https://discourse.paraview.org/t/programmable-filter-gives-wrong-results/12492/1 "2023-07-11T09:38:56Z")

</div>

[error.pvsm](https://discourse.paraview.org/uploads/short-url/23EJ7PAcEINX7Tdvh32pWlTBsmX.pvsm) (954.5 KB)

I have two .vtu files (field1 and field2) which contain one scalar field each defined on a rectangular grid.  
I want to compute the absolute error and the relative error between them.

Attached is a .pvsm file which contain the two input files, and a programmable filter to compute the errors between them. Also, there are three ProbeLocation objects to evaluate the two input files and the computed errors at an arbitrary point in the grid. Lets call this point P.

Interestingly, the absolute error (field1(P) - field2(P)) is correct, which I can verify by the ProbeLocation on the two input files, however, the relative error (field1(P)-field2(P))/field1(P) is clearly wrong. In particular, I have field1(P) = 0.312567, field2(P) = 0.310265, (field1(P) - field2(P) = 0.00230214, (field1(P)-field2(P))/field1(P) = 0.0116339. I double-checked in matlab that the absolute error is correct, only the relative error is wrong.

This looks like a bug to me, or is there something I make wrong?

---

<div class="post-metadata">

### Author: ![Francois\_Mazen](https://discourse.paraview.org/user_avatar/discourse.paraview.org/francois_mazen/32/6483_2.png) [@Francois\_Mazen](https://discourse.paraview.org/u/Francois_Mazen)
#### Post date: [July 12, 2023, 7:05am UTC](https://discourse.paraview.org/t/programmable-filter-gives-wrong-results/12492/2 "2023-07-12T07:05:36Z")

</div>

The vtu files are not contained in the pvsm state file. Could you share them?

---

<div class="post-metadata">

### Author: ![simonw](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@simonw](https://discourse.paraview.org/u/simonw)
#### Post date: [July 12, 2023, 8:21am UTC](https://discourse.paraview.org/t/programmable-filter-gives-wrong-results/12492/3 "2023-07-12T08:21:48Z")

</div>

[energy\_opt.vtu](https://discourse.paraview.org/uploads/short-url/fTdPk7VIQwwnOlsZYIjSlSPAkea.vtu) (4.6 KB)  
[energy\_ref.vtu](https://discourse.paraview.org/uploads/short-url/weE4IKhf5AjArm3GGFV4EGMcZ89.vtu) (4.5 KB)

Please find attached the .vtu files.

---

<div class="post-metadata">

### Author: ![Kenneth\_Moreland](https://discourse.paraview.org/user_avatar/discourse.paraview.org/kenneth_moreland/32/15033_2.png) [@Kenneth\_Moreland](https://discourse.paraview.org/u/Kenneth_Moreland)
#### Post date: [July 12, 2023, 1:42pm UTC](https://discourse.paraview.org/t/programmable-filter-gives-wrong-results/12492/4 "2023-07-12T13:42:11Z")

</div>

I took a look at your data. The filter is computing the correct values at every point. The problem is happening with the interpolation. Your `Probe Location` requires ParaView to interpolate a value inside a cell, and ParaView’s interpolation is not accurate (and there is no reasonable way it could ever be).

ParaView is using linear interpolation within your cells. (More specifically, it is using bi-linear interpolation in your quad cells.) That’s fine for expressions like `ref-opt` for the absolute error because that expression is linear. But your expression for relative error, `(ref-opt)/ref` is nonlinear. Your probe location is near where `ref` is close to zero, where the equation goes pretty crazy. That is why you are getting values that are so off.

You might want to consider using a different equation for relative error. The problem with dividing by each value is that the relative errors are fairly incomparable with each other. When the reference value is near zero, your error is going to shoot up even if you’re within the same range. And note that you are getting a NaN when the reference value is 0. Consider instead using the range of values (`max(ref) - min(ref)`) or the largest absolute value (`max(abs(ref))`). This will solve the problem of your relative error going wonky as the reference values approach 0 and will make your expressing linear, which will solve the interpolation error.

---

<div class="post-metadata">

### Author: ![simonw](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@simonw](https://discourse.paraview.org/u/simonw)
#### Post date: [July 12, 2023, 3:06pm UTC](https://discourse.paraview.org/t/programmable-filter-gives-wrong-results/12492/5 "2023-07-12T15:06:25Z")

</div>

Thank you for taking your time! Let me please ask some follow-up questions:

> Your probe location is near where `ref` is close to zero, where the equation goes pretty crazy. That is why you are getting values that are so off.

I also probed at different locations where ref is far from being zero and observed similar inaccuracies. I think the problem comes. But as you said, the relative error at the vertices is correct.

> But your expression for relative error, `(ref-opt)/ref` is nonlinear.

What I did in matlab is (Interp(ref) - Interp(opt)) / Interp(ref), where Interp(…) denotes bilinear interpolation. But when I write (ref-opt)/ref in the programmable filter, this translates into  
Interp( (ref-opt)/ref ). Is this the reason why the relative is not what I expected?

> Consider instead using the range of values (`max(ref) - min(ref)`) or the largest absolute value (`max(abs(ref))`)

You mean defining the relative error as (ref - opt)/ max(abs(ref)) , for instance?

---

<div class="post-metadata">

### Author: ![Kenneth\_Moreland](https://discourse.paraview.org/user_avatar/discourse.paraview.org/kenneth_moreland/32/15033_2.png) [@Kenneth\_Moreland](https://discourse.paraview.org/u/Kenneth_Moreland)
#### Post date: [July 12, 2023, 3:20pm UTC](https://discourse.paraview.org/t/programmable-filter-gives-wrong-results/12492/6 "2023-07-12T15:20:20Z")

</div>

> [@simonw](#):
>
> What I did in matlab is (Interp(ref) - Interp(opt)) / Interp(ref), where Interp(…) denotes bilinear interpolation. But when I write (ref-opt)/ref in the programmable filter, this translates into  
> Interp( (ref-opt)/ref ). Is this the reason why the relative is not what I expected?

Correct. Matlab is interpolating the operands first whereas ParaView is interpolating the result. If you were to first probe the location and then apply your filter, you should get the expected result.

> [@simonw](#):
>
> You mean defining the relative error as (ref - opt)/ max(abs(ref)) , for instance?

Yes, this is what I mean.

---

<div class="post-metadata">

### Author: ![simonw](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@simonw](https://discourse.paraview.org/u/simonw)
#### Post date: [July 12, 2023, 3:33pm UTC](https://discourse.paraview.org/t/programmable-filter-gives-wrong-results/12492/7 "2023-07-12T15:33:16Z")

</div>

> [@Kenneth\_Moreland](#):
>
> If you were to first probe the location and then apply your filter, you should get the expected result.

What do you mean by probe in this context? If I say probe, I refer to the “Probe Location” filter. But I do not know how this filter effects the programmable filter.  
Or let me reformulate my question:  
Currently, I write (ref-opt)/ref in the programmable filter. What would I have to write instead to get the “expected” results?

---

<div class="post-metadata">

### Author: ![Kenneth\_Moreland](https://discourse.paraview.org/user_avatar/discourse.paraview.org/kenneth_moreland/32/15033_2.png) [@Kenneth\_Moreland](https://discourse.paraview.org/u/Kenneth_Moreland)
#### Post date: [July 12, 2023, 3:43pm UTC](https://discourse.paraview.org/t/programmable-filter-gives-wrong-results/12492/8 "2023-07-12T15:43:58Z")

</div>

> [@simonw](#):
>
> What do you mean by probe in this context? If I say probe, I refer to the “Probe Location” filter.

I mean the same thing. What I mean is to run `Probe Location` on the two input files and then run your `Programmable Filter` on the outputs of the probes. So, this is basically reversing the order of operations (probe location first then filter instead of filter then probe).

---

<div class="post-metadata">

### Author: ![simonw](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@simonw](https://discourse.paraview.org/u/simonw)
#### Post date: [July 12, 2023, 3:49pm UTC](https://discourse.paraview.org/t/programmable-filter-gives-wrong-results/12492/9 "2023-07-12T15:49:57Z")

</div>

> [@Kenneth\_Moreland](#):
>
> I mean the same thing. What I mean is to run `Probe Location` on the two input files and then run your `Programmable Filter` on the outputs of the probes. So, this is basically reversing the order of operations (probe location first then filter instead of filter then probe).

I see. But my understanding of Probe Location is to probe the fields of interest at a small number of points. So going your way, I would evaluate the relative error only at the points that I defined in Probe Location but I would not get a new field containing all points, right?

---

<div class="post-metadata">

### Author: ![Kenneth\_Moreland](https://discourse.paraview.org/user_avatar/discourse.paraview.org/kenneth_moreland/32/15033_2.png) [@Kenneth\_Moreland](https://discourse.paraview.org/u/Kenneth_Moreland)
#### Post date: [July 12, 2023, 5:54pm UTC](https://discourse.paraview.org/t/programmable-filter-gives-wrong-results/12492/10 "2023-07-12T17:54:19Z")

</div>

> [@simonw](#):
>
> So going your way, I would evaluate the relative error only at the points that I defined in Probe Location but I would not get a new field containing all points, right?

Correct. I’m not necessarily saying this should be the way you should go. That all depends on what you are doing this for. I was mostly just trying to demonstrate the problem and the differences between ParaView and Matlab.

More commonly, you might resample your data (say with `Resample To Image`) to a fine enough level where the difference from linear interpolation is tolerable.

---

<div class="post-metadata">

### Author: ![simonw](https://discourse.paraview.org/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@simonw](https://discourse.paraview.org/u/simonw)
#### Post date: [July 12, 2023, 9:04pm UTC](https://discourse.paraview.org/t/programmable-filter-gives-wrong-results/12492/11 "2023-07-12T21:04:27Z")

</div>

> [@Kenneth\_Moreland](#):
>
> Correct. I’m not necessarily saying this should be the way you should go. That all depends on what you are doing this for. I was mostly just trying to demonstrate the problem and the differences between ParaView and Matlab.

Last question:

Is there a solution to have the relative error as a new field (just right now with the programmable filter), but with the formulae (Interp(ref) - Interp(opt) ) / Interp(ref) instead of Interp( (ref - opt)/ref ) ?

---

<div class="post-metadata">

### Author: ![Kenneth\_Moreland](https://discourse.paraview.org/user_avatar/discourse.paraview.org/kenneth_moreland/32/15033_2.png) [@Kenneth\_Moreland](https://discourse.paraview.org/u/Kenneth_Moreland)
#### Post date: [July 13, 2023, 2:46pm UTC](https://discourse.paraview.org/t/programmable-filter-gives-wrong-results/12492/12 "2023-07-13T14:46:39Z")

</div>

Short answer: no. That would require defining a field as a function, and that is just not supported in VTK.

The closest thing I can think of is to define an expression for the `Calculator` filter that could be applied wherever you need it. I would start by combining the ref and opt arrays into one dataset (which you can do with the `Rename Arrays` and `Append Attributes` filters. From there, you can use the simple `Calculator` filter to find the relative error whenever you need it. The `Calculator` filter now allows you to save expressions, which makes it easier to apply the same thing over and over again.
