Re: mutable considered harmful, Range edition

"John W. Eaton" <[email protected]>
Newsgroups gmane.comp.gnu.octave.maintainers
Message-ID <[email protected]>
On 6/9/20 12:11 AM, I wrote:

> Separately, I see that other than the Range::matrix_value method, we set 
> the cache value in the operators, like this:
> 
>    Range operator + (const Range& r, double x)
>    {
>      Range result (r.base () + x, r.limit () + x, r.inc (), r.numel ());
>      if (result.m_numel < 0)
>        result.m_cache = r.matrix_value () + x;
> 
>      return result;
>    }
> 
> As I recall, setting the cache in these functions (and not just the 
> matrix_value method) is done so that, for example, adding a constant to 
> a range and then converting to a matrix will produce exactly the same 
> result as converting a range to a matrix and then adding a constant to 
> the matrix (in psuedo code):
> 
>    matrix (r) + c == matrix (r + c)
> 
> Using the cache this way does avoid the cost of any repeated conversions 
> to a matrix value, but it also forces the cache to be created for any 
> operation on a range, not just the result.  So it largely defeats the 
> purpose of the efficient range object storage, and I'm wondering whether 
> it is worth having a special range data type at all?  What do we really 
> gain for the additional complexity?

I see now that there are limited cases where result.m_numel will be 
negative, so the cache is not updated for every operation.  However, the 
problems with the mutable cache remain, as do the issues with operations 
on ranges not being identical to the operations on the equivalent 
matrices.  Here is a simple example:

   r0 = 1:0.1:10;
   r1 = r0 + 2.3;   # range + scalar
   r2 = [r0] + 2.3; # matrix + scalar
   all (r1 == r2)   # returns false for me
   d = r1 - r2;     # show elements with differences
   idx = find (d)
   d(idx)

I understand the arguments about Octave being a numerical tool and not 
expecting exact results for floating point operations, but I'm still 
wondering whether the complexity of these range operations is justified. 
  If we do want to support operations that avoid immediate conversion to 
Matrix data, maybe we should only do so when we can guarantee that

   matrix (r) OP val == matrix (r OP val)

is true?  We should be able to do this when VAL and all elements of R 
are integers and will remain so after the operation.  Other cases might 
be possible as well, but harder to detect.  And maybe the cache should 
be eliminated and this test handled in the octave_value class hierarchy?

jwe
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.