You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Sébastien Brisard <se...@m4x.org> on 2011/08/11 05:36:40 UTC

[math] Read-only RealVector

Hello,
this is an idea I've had while thinking about Iterative Linear
Solvers, but I think it is much more general. I don't know whether
what I'm going to describe is a known pattern, or a very dirty trick I
should forget about. So any advice would be greatly appreciated.

For the sake of the argument, let us stick with iterative linear
solvers. Most of them modify in-place the current estimate of the
solution, x (which is a RealVector). In view of observing the state of
the solver during the iterations, I'd like to provide a method
RealVector getCurrentSolution()

As modifying the current solution outside the solver would ruin the
iterations, it is imperative to return a deep copy of x. This can take
time, if the vector is large. Also, it can be memory consuming. So I
was wondering: would it be possible to design a ReadOnlyRealVector
class, which would be final, have a unique constructor
ReadOnlyRealVector(RealVector v)
and extend AbstractRealVector

I would keep a reference to the underlying RealVector used to
construct the ReadOnlyRealVector, so that any call to a standard
RealVector method would be delegated to the same method in v. EXCEPT
when the method in question would normally modify the
ReadOnlyRealVector, in which case an UnsupportedException would be
thrown. For example

v = new RealVector();
...
vro = new ReadOnlyRealVector(v);
vro.map(f); // Returns v.map(f)
vro.mapToSelf(f); // Throws an exception

Note that "Read-Only" does not mean "Immutable", since a modification
of v would modify vro. This would suit my requirements, but it should
be made clear in the Javadoc.
Is it clean code, or should I throw it away?
In the former case, would a ReadOnly tagging interface make sense?

Thanks for your comments/corrections,
Sebastien

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Gilles Sadowski <gi...@harfang.homelinux.org>.
On Thu, Aug 11, 2011 at 01:16:32PM +0200, Luc Maisonobe wrote:
> Le 11/08/2011 12:24, Sébastien Brisard a écrit :
> >>
> >>Well, in fact I would very much like to have immutable vectors too.
> >>Immutability is really a way to simplify implementations. Surprisingly it
> >>sometimes also decrease time and memory consumption, because defensive
> >>copies littering user code can be avoided.
> >>
> >Luc, I have a silly question. Why do you think immutable vectors would
> >prevent defensive copy ? Creating an immutable vector from an existing
> >mutable vector would require a defensive copy, wouldn't it?
> 
> Yes, of course. What I meant is that when users don't have the
> choice and are forced to use only mutable objects, then in many
> places they do defensive copying, just because they do not even know
> if some other code will attempt to modify the object in place after
> they have retrieved it. So you end up with "B b = a.getB().clone()"
> to protect the B instance.
> 
> When instances are known to be immutable, you don't copy them (and
> you often neither implement Cloneable nor set up copy constructors).
> 
> >Thats the reason why I'm talking about read-only vectors, and not
> >immutable vectors.
> >The solver would keep a reference to the underlying (mutable) vector,
> >so would be able to modify (indirectly) the read-only vector.
> >The observer would only have a reference to the read-only vector, so
> >would not be able to modify the underlying vector.
> 
> The problem with this approach is that the observer could not
> preserve the instance across several calls (for example to compare
> the instance from one previous call to the current one). If a
> specific observer wants to do that, then it needs to be able to copy
> the instance. If the observer knows the object is immutable, it will
> only preserve the reference.

If the vector must be mutable, because it is changed in place as the
algorithm iterates, and if the checker needs to keep older states, it
must copy the current solution passed to it. Thus you don't save
anything (a copy must be made either in the solver or in the checker).

With an immutable vector, you create a new intance at each iteration but you
can pass it directly (no copy) and the checker can keep it (also without
making a copy).


Gilles

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Luc Maisonobe <Lu...@free.fr>.
Le 11/08/2011 12:24, Sébastien Brisard a écrit :
>>
>> Well, in fact I would very much like to have immutable vectors too.
>> Immutability is really a way to simplify implementations. Surprisingly it
>> sometimes also decrease time and memory consumption, because defensive
>> copies littering user code can be avoided.
>>
> Luc, I have a silly question. Why do you think immutable vectors would
> prevent defensive copy ? Creating an immutable vector from an existing
> mutable vector would require a defensive copy, wouldn't it?

Yes, of course. What I meant is that when users don't have the choice 
and are forced to use only mutable objects, then in many places they do 
defensive copying, just because they do not even know if some other code 
will attempt to modify the object in place after they have retrieved it. 
So you end up with "B b = a.getB().clone()" to protect the B instance.

When instances are known to be immutable, you don't copy them (and you 
often neither implement Cloneable nor set up copy constructors).

> Thats the reason why I'm talking about read-only vectors, and not
> immutable vectors.
> The solver would keep a reference to the underlying (mutable) vector,
> so would be able to modify (indirectly) the read-only vector.
> The observer would only have a reference to the read-only vector, so
> would not be able to modify the underlying vector.

The problem with this approach is that the observer could not preserve 
the instance across several calls (for example to compare the instance 
from one previous call to the current one). If a specific observer wants 
to do that, then it needs to be able to copy the instance. If the 
observer knows the object is immutable, it will only preserve the reference.

Luc

>
> Sébastien
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Sébastien Brisard <se...@m4x.org>.
I'm sorry. Coming up to work, I've realized that my previous
suggestion was silly.
>
> Instead of having a method
> RealVector getSolution()
> how about specifying
> RealVector getSolution(boolean deep)
> if deep is true, it returns a deep copy, if not it MIGHT (but the
> contract of the method does not make it compulsory) return a shallow
> copy. The Javadoc should clearly state that if deep is true, then the
> user should not modify the returned vector.
>

I'd like to withdraw it and not waste your time with that. Sorry again.
I can submit some code regarding unmodifiableRealVector(RealVector v)
very soon, I hope.
Best regards for now,
Sebastien

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Phil Steitz <ph...@gmail.com>.
On 8/11/11 8:41 PM, Sébastien Brisard wrote:
> Hi,
> it's clear I think that there is no really fool-proof solution, but
> that's OK I think. The idea would be to avoid accidental modifications
> which could be catastrophic. But nothing could prevent an evil
> programmer to do its evil job. I like what was earlier pointed out:
> Javadoc should be very detailed on these issues.
> About having a really immutable vector, it's of course a desirable
> feature, but thinking about it, it would be nice to be able to combine
> both immutable vectors and mutable vectors. Question is: should the
> result be mutable or immutable ? Example
> immutale.add(mutable), and the converse mutable.add(immutable). Should
> the results be mutable? immutable?
> Following the approach in UmmodifiableCollections is probably what
> I'll do, except if you like the following (VEEEEERY simple) approach
> better. Instead of having a method
> RealVector getSolution()
> how about specifying
> RealVector getSolution(boolean deep)
> if deep is true, it returns a deep copy, if not it MIGHT (but the
> contract of the method does not make it compulsory) return a shallow
> copy. The Javadoc should clearly state that if deep is true, then the
> user should not modify the returned vector.
> Looking forward to hearing what you think,

I see Gilles' suggestion to add
public static RealVector unmodifiableRealVector(RealVector v) to
AbstractRealVector as a valuable addition, independent of this use
case, and similarly for matrices, implemented using the decorator
pattern the way that Harmony, [collections] and I assume the JDK
does it. So I would vote for that approach and to in general have
getSolution() methods return either copies or unmodifiable views of
results. In this case, I would keep it simple and just have
getSolution return an unmodifiable view (documented in javadoc, of
course).  Note that AbstractRealVector has a copy method and as long
as (the private inner class) UnmodifiableRealVector delegates that
method through, users will be able to create modifiable copies
themselves if they need to.

Phil
> Sebastien
>
>
> 2011/8/11 Phil Steitz <ph...@gmail.com>:
>> On 8/11/11 4:22 AM, Gilles Sadowski wrote:
>>> Hello Sébastien.
>>>
>>>>> Well, in fact I would very much like to have immutable vectors too.
>>>>> Immutability is really a way to simplify implementations. Surprisingly it
>>>>> sometimes also decrease time and memory consumption, because defensive
>>>>> copies littering user code can be avoided.
>>>>>
>>>> Luc, I have a silly question. Why do you think immutable vectors would
>>>> prevent defensive copy ? Creating an immutable vector from an existing
>>>> mutable vector would require a defensive copy, wouldn't it?
>>>> Thats the reason why I'm talking about read-only vectors, and not
>>>> immutable vectors.
>>>> The solver would keep a reference to the underlying (mutable) vector,
>>>> so would be able to modify (indirectly) the read-only vector.
>>>> The observer would only have a reference to the read-only vector, so
>>>> would not be able to modify the underlying vector.
>>> I think that you were right to stress the difference between immutable and
>>> read-only.
>>> If I'm not mistaken, in JDK parlance they call the latter "unmodifiable"
>>> (cf. the methods "unmodifiableCollection" and siblings in the standard class
>>> "java.util.Collections").
>>>
>>> The idea which you referred to at the beginning of this thread is exactly
>>> what they do: The wrapping class throws "UnsupportedOperationException" from
>>> any "mutating" method.
>>>
>>> What Luc said is that when you pass an (already) immutable object, you do not
>>> have to make a copy; a reference is as safe.
>>>
>>> I'm not sure whether that would still be true with an unmodifiable
>>> reference. I.e. couldn't it be cast to its underlying modifiable reference?
>>> However that would be on-purpose nasty code, not a mistake on the part of
>>> the checker code.
>>>
>>> So, a utility method like
>>>   public static RealVector unmodifiableRealVector(RealVector v)
>>> in class "AbstractRealVector", would fit your need, IMO.
>> +1 - looks to me like what is needed is an unmodifiable view,
>> exactly like what the UnmodifiableCollections provide.   What is
>> returned in the methods analogous to the above in
>> Collections.unModifiableXxx are instances of private static inner
>> classes that decorate the actual parameter and delegate, throwing
>> UnsupportedOperationExceptions for mutators.  See either
>> [collections] or the Harmony code [1] for examples.
>>
>> Phil
>>
>> [1] http://s.apache.org/XJ4
>>>
>>> Best,
>>> Gilles
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>>> For additional commands, e-mail: dev-help@commons.apache.org
>>>
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
>>
>>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Sébastien Brisard <se...@m4x.org>.
Hi,
it's clear I think that there is no really fool-proof solution, but
that's OK I think. The idea would be to avoid accidental modifications
which could be catastrophic. But nothing could prevent an evil
programmer to do its evil job. I like what was earlier pointed out:
Javadoc should be very detailed on these issues.
About having a really immutable vector, it's of course a desirable
feature, but thinking about it, it would be nice to be able to combine
both immutable vectors and mutable vectors. Question is: should the
result be mutable or immutable ? Example
immutale.add(mutable), and the converse mutable.add(immutable). Should
the results be mutable? immutable?
Following the approach in UmmodifiableCollections is probably what
I'll do, except if you like the following (VEEEEERY simple) approach
better. Instead of having a method
RealVector getSolution()
how about specifying
RealVector getSolution(boolean deep)
if deep is true, it returns a deep copy, if not it MIGHT (but the
contract of the method does not make it compulsory) return a shallow
copy. The Javadoc should clearly state that if deep is true, then the
user should not modify the returned vector.
Looking forward to hearing what you think,
Sebastien


2011/8/11 Phil Steitz <ph...@gmail.com>:
> On 8/11/11 4:22 AM, Gilles Sadowski wrote:
>> Hello Sébastien.
>>
>>>> Well, in fact I would very much like to have immutable vectors too.
>>>> Immutability is really a way to simplify implementations. Surprisingly it
>>>> sometimes also decrease time and memory consumption, because defensive
>>>> copies littering user code can be avoided.
>>>>
>>> Luc, I have a silly question. Why do you think immutable vectors would
>>> prevent defensive copy ? Creating an immutable vector from an existing
>>> mutable vector would require a defensive copy, wouldn't it?
>>> Thats the reason why I'm talking about read-only vectors, and not
>>> immutable vectors.
>>> The solver would keep a reference to the underlying (mutable) vector,
>>> so would be able to modify (indirectly) the read-only vector.
>>> The observer would only have a reference to the read-only vector, so
>>> would not be able to modify the underlying vector.
>> I think that you were right to stress the difference between immutable and
>> read-only.
>> If I'm not mistaken, in JDK parlance they call the latter "unmodifiable"
>> (cf. the methods "unmodifiableCollection" and siblings in the standard class
>> "java.util.Collections").
>>
>> The idea which you referred to at the beginning of this thread is exactly
>> what they do: The wrapping class throws "UnsupportedOperationException" from
>> any "mutating" method.
>>
>> What Luc said is that when you pass an (already) immutable object, you do not
>> have to make a copy; a reference is as safe.
>>
>> I'm not sure whether that would still be true with an unmodifiable
>> reference. I.e. couldn't it be cast to its underlying modifiable reference?
>> However that would be on-purpose nasty code, not a mistake on the part of
>> the checker code.
>>
>> So, a utility method like
>>   public static RealVector unmodifiableRealVector(RealVector v)
>> in class "AbstractRealVector", would fit your need, IMO.
>
> +1 - looks to me like what is needed is an unmodifiable view,
> exactly like what the UnmodifiableCollections provide.   What is
> returned in the methods analogous to the above in
> Collections.unModifiableXxx are instances of private static inner
> classes that decorate the actual parameter and delegate, throwing
> UnsupportedOperationExceptions for mutators.  See either
> [collections] or the Harmony code [1] for examples.
>
> Phil
>
> [1] http://s.apache.org/XJ4
>>
>>
>> Best,
>> Gilles
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Phil Steitz <ph...@gmail.com>.
On 8/11/11 4:22 AM, Gilles Sadowski wrote:
> Hello Sébastien.
>
>>> Well, in fact I would very much like to have immutable vectors too.
>>> Immutability is really a way to simplify implementations. Surprisingly it
>>> sometimes also decrease time and memory consumption, because defensive
>>> copies littering user code can be avoided.
>>>
>> Luc, I have a silly question. Why do you think immutable vectors would
>> prevent defensive copy ? Creating an immutable vector from an existing
>> mutable vector would require a defensive copy, wouldn't it?
>> Thats the reason why I'm talking about read-only vectors, and not
>> immutable vectors.
>> The solver would keep a reference to the underlying (mutable) vector,
>> so would be able to modify (indirectly) the read-only vector.
>> The observer would only have a reference to the read-only vector, so
>> would not be able to modify the underlying vector.
> I think that you were right to stress the difference between immutable and
> read-only.
> If I'm not mistaken, in JDK parlance they call the latter "unmodifiable"
> (cf. the methods "unmodifiableCollection" and siblings in the standard class
> "java.util.Collections").
>
> The idea which you referred to at the beginning of this thread is exactly
> what they do: The wrapping class throws "UnsupportedOperationException" from
> any "mutating" method.
>
> What Luc said is that when you pass an (already) immutable object, you do not
> have to make a copy; a reference is as safe.
>
> I'm not sure whether that would still be true with an unmodifiable
> reference. I.e. couldn't it be cast to its underlying modifiable reference?
> However that would be on-purpose nasty code, not a mistake on the part of
> the checker code.
>
> So, a utility method like
>   public static RealVector unmodifiableRealVector(RealVector v)
> in class "AbstractRealVector", would fit your need, IMO.

+1 - looks to me like what is needed is an unmodifiable view,
exactly like what the UnmodifiableCollections provide.   What is
returned in the methods analogous to the above in
Collections.unModifiableXxx are instances of private static inner
classes that decorate the actual parameter and delegate, throwing
UnsupportedOperationExceptions for mutators.  See either
[collections] or the Harmony code [1] for examples.

Phil

[1] http://s.apache.org/XJ4
>
>
> Best,
> Gilles
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Gilles Sadowski <gi...@harfang.homelinux.org>.
Hello Sébastien.

> >
> > Well, in fact I would very much like to have immutable vectors too.
> > Immutability is really a way to simplify implementations. Surprisingly it
> > sometimes also decrease time and memory consumption, because defensive
> > copies littering user code can be avoided.
> >
> Luc, I have a silly question. Why do you think immutable vectors would
> prevent defensive copy ? Creating an immutable vector from an existing
> mutable vector would require a defensive copy, wouldn't it?
> Thats the reason why I'm talking about read-only vectors, and not
> immutable vectors.
> The solver would keep a reference to the underlying (mutable) vector,
> so would be able to modify (indirectly) the read-only vector.
> The observer would only have a reference to the read-only vector, so
> would not be able to modify the underlying vector.

I think that you were right to stress the difference between immutable and
read-only.
If I'm not mistaken, in JDK parlance they call the latter "unmodifiable"
(cf. the methods "unmodifiableCollection" and siblings in the standard class
"java.util.Collections").

The idea which you referred to at the beginning of this thread is exactly
what they do: The wrapping class throws "UnsupportedOperationException" from
any "mutating" method.

What Luc said is that when you pass an (already) immutable object, you do not
have to make a copy; a reference is as safe.

I'm not sure whether that would still be true with an unmodifiable
reference. I.e. couldn't it be cast to its underlying modifiable reference?
However that would be on-purpose nasty code, not a mistake on the part of
the checker code.

So, a utility method like
  public static RealVector unmodifiableRealVector(RealVector v)
in class "AbstractRealVector", would fit your need, IMO.


Best,
Gilles

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Sébastien Brisard <se...@m4x.org>.
>
> Well, in fact I would very much like to have immutable vectors too.
> Immutability is really a way to simplify implementations. Surprisingly it
> sometimes also decrease time and memory consumption, because defensive
> copies littering user code can be avoided.
>
Luc, I have a silly question. Why do you think immutable vectors would
prevent defensive copy ? Creating an immutable vector from an existing
mutable vector would require a defensive copy, wouldn't it?
Thats the reason why I'm talking about read-only vectors, and not
immutable vectors.
The solver would keep a reference to the underlying (mutable) vector,
so would be able to modify (indirectly) the read-only vector.
The observer would only have a reference to the read-only vector, so
would not be able to modify the underlying vector.

Sébastien

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Luc Maisonobe <Lu...@free.fr>.
Le 11/08/2011 13:29, Sébastien Brisard a écrit :
>>
>> You can also have a common interface without modification methods, and two
>> implementations, an immutable one and a mutable one (I think this is how
>> Scala containers are designed).
>>
>> Luc
>>
> That is I suppose the cleanest approach, but within the solver's loop,
> I need the current solution to be modifiable, while I need the
> solution returned by getSolution() to be read-only. therefore, if I
> have those two implementations, I will need a deep copy somewhere, no?
> Or would the solver be creating a new (immutable) vector at each
> iteration? Maybe this is not so much of an overhead, after all. How
> about memory?

Perhaps a top level immutable class and a derived mutable class would 
avoid copying. Internally, the algorithm would know its instance is 
mutable, but it would not advertise it outside and the signature would 
only return the immutable class.

This is however neither really clean nor foolproof. Users may think the 
reference they get is immutable for everyone, so they could store a 
reference, but as the algorithm may change it under the hood, it would 
break users assumptions.

Concerning memory, I would say that with modern computer, copying a few 
megabytes is really not a problem. This does not scale up to gigabytes 
or terabytes. In these cases, I guess we can rely only on documentation 
and warn users that they get a reference to internal objects and that 
they should *never* change them. The only thing we can do to improve 
this is adding a read-only wrapper as you suggested (I think) some 
messages ago.

There is no perfect solution.

Luc

> On the other hand, referring to your previous message: I actually like
> the fact that the observer is responsible for making deep copies. By
> default, this minimizes the number of deep-copies.
>>>
>>> Sebastien
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>>> For additional commands, e-mail: dev-help@commons.apache.org
>>>
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Sébastien Brisard <se...@m4x.org>.
>
> You can also have a common interface without modification methods, and two
> implementations, an immutable one and a mutable one (I think this is how
> Scala containers are designed).
>
> Luc
>
That is I suppose the cleanest approach, but within the solver's loop,
I need the current solution to be modifiable, while I need the
solution returned by getSolution() to be read-only. therefore, if I
have those two implementations, I will need a deep copy somewhere, no?
Or would the solver be creating a new (immutable) vector at each
iteration? Maybe this is not so much of an overhead, after all. How
about memory?
On the other hand, referring to your previous message: I actually like
the fact that the observer is responsible for making deep copies. By
default, this minimizes the number of deep-copies.
>>
>> Sebastien
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Luc Maisonobe <Lu...@free.fr>.
Le 11/08/2011 13:10, Sébastien Brisard a écrit :
> 2011/8/11 sebb<se...@gmail.com>:
>> 2011/8/11 Sébastien Brisard<se...@m4x.org>:
>>> OK, this I also think would be useful. But my initial question
>>> remains, if the object I want to protect is not a RealVector, what do
>>> you think of my solution ?
>>> Sébastien
>>
>> If you create the read-only version by subclassing the writable
>> version, then you have to ensure that all mutating methods are
>> overridden.
>> If a base class is later extended to add a new mutator, the protection is lost.
> That's quite true... Didn't think of that. It pretty much ruins it, doesn't it?

You can also have a common interface without modification methods, and 
two implementations, an immutable one and a mutable one (I think this is 
how Scala containers are designed).

Luc

>
> Sebastien
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Sébastien Brisard <se...@m4x.org>.
2011/8/11 sebb <se...@gmail.com>:
> 2011/8/11 Sébastien Brisard <se...@m4x.org>:
>> OK, this I also think would be useful. But my initial question
>> remains, if the object I want to protect is not a RealVector, what do
>> you think of my solution ?
>> Sébastien
>
> If you create the read-only version by subclassing the writable
> version, then you have to ensure that all mutating methods are
> overridden.
> If a base class is later extended to add a new mutator, the protection is lost.
That's quite true... Didn't think of that. It pretty much ruins it, doesn't it?

Sebastien

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by sebb <se...@gmail.com>.
2011/8/11 Sébastien Brisard <se...@m4x.org>:
> OK, this I also think would be useful. But my initial question
> remains, if the object I want to protect is not a RealVector, what do
> you think of my solution ?
> Sébastien

If you create the read-only version by subclassing the writable
version, then you have to ensure that all mutating methods are
overridden.
If a base class is later extended to add a new mutator, the protection is lost.

This can be avoided by using composition, only forwarding safe
methods. However that means the new class is not an instance of the
old class.

Neither is perfect ...

> PS : the problem is likely to occur when listening to other Iterative
> Processes (not only linear solvers). For example, in o.a.c.m.genetics,
> has a StoppingCondition.isSatisfied(Population),
> and Population.addChromosome() would enable the StoppingCondition to
> actually modify the ongoing simulation. Whether it is harmfull, I do
> not know, though.
> So of course, we could come up with a ImmutablePopulation as well, but
> maybe it starts to get complicated?
>
> Sébastien
>
> 2011/8/11 Luc Maisonobe <Lu...@free.fr>:
>> Le 11/08/2011 10:55, Sébastien Brisard a écrit :
>>>
>>> 2011/8/11 Arne Ploese<ap...@gmx.de>:
>>>>
>>>> So you not only want to observe the result, but you want a read only
>>>> RealVector.
>>>>
>>> That's right. I'm sorry, my first message was not clear, especially if
>>> you did not follow the thread on iterative solvers.
>>> I want to observe the *solver*, and the current state of the solver is
>>> a *RealVector*, which should by no means be modified by the observer.
>>> The safest way to do that would be for the solver to have a method
>>> like
>>> public RealVector getCurrentSolution(){
>>>     return x.copy();
>>> }
>>> but that takes both time and memory. So I was thinking of something more
>>> like
>>> public RealVector getCurrentSolution(){
>>>     return new ReadOnlyRealVector(x);
>>> }
>>> which takes virtually no additional memory (and presumably very little
>>> time). The two advantages of this approach are
>>> * it does not jeopardize the whole hierarchy tree, since you do not
>>> have to create a new interface,
>>> * it is quite general, and could be adopted for any base object (not
>>> only RealVector).
>>> The downside is that some methods throw exceptions, which might be
>>> deemed dirty. I don't really know.
>>
>> Well, in fact I would very much like to have immutable vectors too.
>> Immutability is really a way to simplify implementations. Surprisingly it
>> sometimes also decrease time and memory consumption, because defensive
>> copies littering user code can be avoided.
>>
>> Jeopardizing the hierarchy tree is not a problem IMHO.
>>
>> Luc
>>
>>> S
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>>> For additional commands, e-mail: dev-help@commons.apache.org
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Sébastien Brisard <se...@m4x.org>.
OK, this I also think would be useful. But my initial question
remains, if the object I want to protect is not a RealVector, what do
you think of my solution ?
Sébastien

PS : the problem is likely to occur when listening to other Iterative
Processes (not only linear solvers). For example, in o.a.c.m.genetics,
has a StoppingCondition.isSatisfied(Population),
and Population.addChromosome() would enable the StoppingCondition to
actually modify the ongoing simulation. Whether it is harmfull, I do
not know, though.
So of course, we could come up with a ImmutablePopulation as well, but
maybe it starts to get complicated?

Sébastien

2011/8/11 Luc Maisonobe <Lu...@free.fr>:
> Le 11/08/2011 10:55, Sébastien Brisard a écrit :
>>
>> 2011/8/11 Arne Ploese<ap...@gmx.de>:
>>>
>>> So you not only want to observe the result, but you want a read only
>>> RealVector.
>>>
>> That's right. I'm sorry, my first message was not clear, especially if
>> you did not follow the thread on iterative solvers.
>> I want to observe the *solver*, and the current state of the solver is
>> a *RealVector*, which should by no means be modified by the observer.
>> The safest way to do that would be for the solver to have a method
>> like
>> public RealVector getCurrentSolution(){
>>     return x.copy();
>> }
>> but that takes both time and memory. So I was thinking of something more
>> like
>> public RealVector getCurrentSolution(){
>>     return new ReadOnlyRealVector(x);
>> }
>> which takes virtually no additional memory (and presumably very little
>> time). The two advantages of this approach are
>> * it does not jeopardize the whole hierarchy tree, since you do not
>> have to create a new interface,
>> * it is quite general, and could be adopted for any base object (not
>> only RealVector).
>> The downside is that some methods throw exceptions, which might be
>> deemed dirty. I don't really know.
>
> Well, in fact I would very much like to have immutable vectors too.
> Immutability is really a way to simplify implementations. Surprisingly it
> sometimes also decrease time and memory consumption, because defensive
> copies littering user code can be avoided.
>
> Jeopardizing the hierarchy tree is not a problem IMHO.
>
> Luc
>
>> S
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Luc Maisonobe <Lu...@free.fr>.
Le 11/08/2011 10:55, Sébastien Brisard a écrit :
> 2011/8/11 Arne Ploese<ap...@gmx.de>:
>> So you not only want to observe the result, but you want a read only
>> RealVector.
>>
> That's right. I'm sorry, my first message was not clear, especially if
> you did not follow the thread on iterative solvers.
> I want to observe the *solver*, and the current state of the solver is
> a *RealVector*, which should by no means be modified by the observer.
> The safest way to do that would be for the solver to have a method
> like
> public RealVector getCurrentSolution(){
>      return x.copy();
> }
> but that takes both time and memory. So I was thinking of something more like
> public RealVector getCurrentSolution(){
>      return new ReadOnlyRealVector(x);
> }
> which takes virtually no additional memory (and presumably very little
> time). The two advantages of this approach are
> * it does not jeopardize the whole hierarchy tree, since you do not
> have to create a new interface,
> * it is quite general, and could be adopted for any base object (not
> only RealVector).
> The downside is that some methods throw exceptions, which might be
> deemed dirty. I don't really know.

Well, in fact I would very much like to have immutable vectors too. 
Immutability is really a way to simplify implementations. Surprisingly 
it sometimes also decrease time and memory consumption, because 
defensive copies littering user code can be avoided.

Jeopardizing the hierarchy tree is not a problem IMHO.

Luc

> S
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Arne Ploese <ap...@gmx.de>.
Am Donnerstag, den 11.08.2011, 10:55 +0200 schrieb Sébastien Brisard: 
> 2011/8/11 Arne Ploese <ap...@gmx.de>:
> > So you not only want to observe the result, but you want a read only
> > RealVector.
> >
> That's right. I'm sorry, my first message was not clear, especially if
> you did not follow the thread on iterative solvers.
> I want to observe the *solver*, and the current state of the solver is
> a *RealVector*, which should by no means be modified by the observer.
> The safest way to do that would be for the solver to have a method
> like
> public RealVector getCurrentSolution(){
>     return x.copy();
> }
> but that takes both time and memory. So I was thinking of something more like
> public RealVector getCurrentSolution(){
>     return new ReadOnlyRealVector(x);
> }
> which takes virtually no additional memory (and presumably very little
> time). The two advantages of this approach are
> * it does not jeopardize the whole hierarchy tree, since you do not
> have to create a new interface,
That is true, but you dont get a compile time error if you pass the
instance by accident to somewhere and that one tries to do an xxxToSelf,
which will result in a RuntimeError - not a very clean solution ... more
a hot fix. Having an interface would clear state what you can do and
what not.
> * it is quite general, and could be adopted for any base object (not
> only RealVector).
> The downside is that some methods throw exceptions, which might be
> deemed dirty. I don't really know.
> S



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Sébastien Brisard <se...@m4x.org>.
2011/8/11 Arne Ploese <ap...@gmx.de>:
> So you not only want to observe the result, but you want a read only
> RealVector.
>
That's right. I'm sorry, my first message was not clear, especially if
you did not follow the thread on iterative solvers.
I want to observe the *solver*, and the current state of the solver is
a *RealVector*, which should by no means be modified by the observer.
The safest way to do that would be for the solver to have a method
like
public RealVector getCurrentSolution(){
    return x.copy();
}
but that takes both time and memory. So I was thinking of something more like
public RealVector getCurrentSolution(){
    return new ReadOnlyRealVector(x);
}
which takes virtually no additional memory (and presumably very little
time). The two advantages of this approach are
* it does not jeopardize the whole hierarchy tree, since you do not
have to create a new interface,
* it is quite general, and could be adopted for any base object (not
only RealVector).
The downside is that some methods throw exceptions, which might be
deemed dirty. I don't really know.
S

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Arne Ploese <ap...@gmx.de>.
So you not only want to observe the result, but you want a read only
RealVector.

A "clean" solution would be split RealVector in a base interface, which
not modifies any internal Data and a inherited interface which adds
xxxToSelf and setEnty(...). ??? I think this could lead to some
unforseeable side effects - so maybe some test implementation is
necessary to see whats happen.

Am Donnerstag, den 11.08.2011, 10:08 +0200 schrieb Sébastien Brisard: 
> 2011/8/11 Arne Ploese <ap...@gmx.de>:
> > What methods do you need?
> >
> > Maybe an interface with:
> > public interface SimpleRealVector {
> >  double getEntry(int i);
> >  int getDimension();
> > }
> > will do?
> >
> No, I'd like to have *all* methods of the o.a.c.m.linear.RealVector
> interface, *except* those which modify the caller object, e.g.
> xxxToSelf and setXxx.
> My question was actually more general. To make an object unmodifiable,
> is it good practice to encapsulate it into another object, with
> seamingly the same interface, but unimplemented methods which might
> modify the object ? My point would be not to create any new
> interface/abstract class.
> 
> Below is a quick example (which I hope is not buggy).
> Thanks for your advice,
> Sébastien
> 
> /**********/
> public abstract class AbstractFoo{
>   public abstract double getValue();
> 
>   public abstract void setValue(final double x);
> 
>   public abstract AbstractFoo add(AbstractFoo bar);
> 
>   public void addToSelf(AbstractFoo bar){
>     setValue(getValue + bar.getValue());
>   }
> }
> 
> /**********/
> public class  Foo extends AbstractFoo{
>   private double value;
> 
>   public Foo(final double x){
>     value = x;
>   }
> 
>   public double getValue(){
>     return value;
>   }
> 
>   public void setValue(final double x){
>     value = x;
>   }
> 
>   public AbstractFoo add(AbstractFoo bar){
>     return new Foo(value + bar.getValue());
>   }
> }
> 
> /**********/
> public final class FooReadOnly extends AbstractFoo{
>   private final Foo foo;
> 
>   public FooReadOnly(AbstractFoo foo){
>     this.foo = foo;
> 
>   public double getValue(){
>     return foo.getValue();
>   }
> 
>   public void setValue(final double x){
>     throw new NotImplementedException("read only object");
>   }
> 
>   public AbstractFoo add(AbstractFoo bar){
>     return foo.add(bar);
>   }
> 
>   public void addToSelf(AbstractFoo bar){
>     throw new NotImplementedException("read only object");
>   }
> }
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Sébastien Brisard <se...@m4x.org>.
2011/8/11 Arne Ploese <ap...@gmx.de>:
> What methods do you need?
>
> Maybe an interface with:
> public interface SimpleRealVector {
>  double getEntry(int i);
>  int getDimension();
> }
> will do?
>
No, I'd like to have *all* methods of the o.a.c.m.linear.RealVector
interface, *except* those which modify the caller object, e.g.
xxxToSelf and setXxx.
My question was actually more general. To make an object unmodifiable,
is it good practice to encapsulate it into another object, with
seamingly the same interface, but unimplemented methods which might
modify the object ? My point would be not to create any new
interface/abstract class.

Below is a quick example (which I hope is not buggy).
Thanks for your advice,
Sébastien

/**********/
public abstract class AbstractFoo{
  public abstract double getValue();

  public abstract void setValue(final double x);

  public abstract AbstractFoo add(AbstractFoo bar);

  public void addToSelf(AbstractFoo bar){
    setValue(getValue + bar.getValue());
  }
}

/**********/
public class  Foo extends AbstractFoo{
  private double value;

  public Foo(final double x){
    value = x;
  }

  public double getValue(){
    return value;
  }

  public void setValue(final double x){
    value = x;
  }

  public AbstractFoo add(AbstractFoo bar){
    return new Foo(value + bar.getValue());
  }
}

/**********/
public final class FooReadOnly extends AbstractFoo{
  private final Foo foo;

  public FooReadOnly(AbstractFoo foo){
    this.foo = foo;

  public double getValue(){
    return foo.getValue();
  }

  public void setValue(final double x){
    throw new NotImplementedException("read only object");
  }

  public AbstractFoo add(AbstractFoo bar){
    return foo.add(bar);
  }

  public void addToSelf(AbstractFoo bar){
    throw new NotImplementedException("read only object");
  }
}

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [math] Read-only RealVector

Posted by Arne Ploese <ap...@gmx.de>.
What methods do you need?

Maybe an interface with:
public interface SimpleRealVector {
  double getEntry(int i);
  int getDimension(); 
}
will do? 

Am Donnerstag, den 11.08.2011, 05:36 +0200 schrieb Sébastien Brisard: 
> Hello,
> this is an idea I've had while thinking about Iterative Linear
> Solvers, but I think it is much more general. I don't know whether
> what I'm going to describe is a known pattern, or a very dirty trick I
> should forget about. So any advice would be greatly appreciated.
> 
> For the sake of the argument, let us stick with iterative linear
> solvers. Most of them modify in-place the current estimate of the
> solution, x (which is a RealVector). In view of observing the state of
> the solver during the iterations, I'd like to provide a method
> RealVector getCurrentSolution()
> 
> As modifying the current solution outside the solver would ruin the
> iterations, it is imperative to return a deep copy of x. This can take
> time, if the vector is large. Also, it can be memory consuming. So I
> was wondering: would it be possible to design a ReadOnlyRealVector
> class, which would be final, have a unique constructor
> ReadOnlyRealVector(RealVector v)
> and extend AbstractRealVector
> 
> I would keep a reference to the underlying RealVector used to
> construct the ReadOnlyRealVector, so that any call to a standard
> RealVector method would be delegated to the same method in v. EXCEPT
> when the method in question would normally modify the
> ReadOnlyRealVector, in which case an UnsupportedException would be
> thrown. For example
> 
> v = new RealVector();
> ...
> vro = new ReadOnlyRealVector(v);
> vro.map(f); // Returns v.map(f)
> vro.mapToSelf(f); // Throws an exception
> 
> Note that "Read-Only" does not mean "Immutable", since a modification
> of v would modify vro. This would suit my requirements, but it should
> be made clear in the Javadoc.
> Is it clean code, or should I throw it away?
> In the former case, would a ReadOnly tagging interface make sense?
> 
> Thanks for your comments/corrections,
> Sebastien
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org