-
-
Notifications
You must be signed in to change notification settings - Fork 491
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refined protocol for _element_constructor_ in element classes with mutability #29101
Comments
comment:1
Some examples for comparison: For basic python types,
Regarding two examples of Sage objects,
|
comment:3
Moving tickets to milestone sage-9.2 based on a review of last modification date, branch status, and severity. |
comment:6
Even though the corresponding check via the flac - if R is self and no_extra_args:
- return x in But I don't know anything about the whole string of consequences coming from this. |
comment:7
Just for fun, I've deleted these lines and ran a doctest:
|
comment:8
Note that
|
comment:9
Replying to @mkoeppe:
Regarding the default |
comment:10
Right. So how about changing this default to |
comment:11
This could only be a temporary solution. As you already pointed out, and I totally agree with you, the element constructor should behave consistently, i.e. always returning a mutable element. Returning the very same instant, assuming it is immutable, would contradict this behavior. |
comment:12
Replying to @mjungmath:
I don't think this is my position; if I did say this, let me try to refine it here. In #30302 comment:3 I pointed out that arithmetic operations need to be consistent: Either always return a new element (even for trivial operations), or always return an immutable element. It is not true that the parent object "is" the element constructor. Its My proposal is to define a general protocol for element classes with mutability which does NOT change the above but only refines it for mutable classes as follows:
We could add |
comment:16
Replying to @mkoeppe:
I was more referring to your first paragraph:
Consider the following code:
I don't see a point if the element constructor sometimes returns a mutable and sometimes an immutable element. This is how I understood your argument that we should I'd say, if |
comment:19
Setting new milestone based on a cursory review of ticket status, priority, and last modification date. |
comment:20
Setting a new milestone for this ticket based on a cursory review. |
This comment has been minimized.
This comment has been minimized.
comment:22
Given that in some parents it is possible to create both mutable and immutable elements, having a
we need a way to have parents that use default value "immutable". In the usual paradigm of mutable data structures, there should be a way of getting an uninitialized mutable element; something like With that in place, there would be a clear expressive way for people to get mutable vectors and matrices, freeing up the default constructors to just produce immutable elements. This would be quite backwards incompatible, but that might be a hit we need to take. Note that for efficient use of mutable elements, we need a whole slew of extra routines as well, because normal expression notation doesn't jive with efficient use of mutable data structures.
See the API of libraries like |
comment:23
For that, we would want to (also?) override |
comment:24
Replying to @tscrim:
Yes. Does the coercion system already have preparation for this at all? |
comment:25
Replying to @mkoeppe:
Strictly speaking, coercion doesn't quite make sense here because the coefficients might have to leave the current coefficient ring (say, we are working over P = self.parent()
if P.has_coerce_map_from(other.parent()):
return self.inplace_add(P(other))
return coercion_model.bin_op(self, other, op) However, we currently do not have, e.g., |
comment:26
I agree, this is not a normal binop-coercion; nevertheless taking care of it is a task for the coercion system, so I'm +1 for single-underscore |
comment:28
Here's the beginning of a
New commits:
|
Commit: |
This comment has been minimized.
This comment has been minimized.
comment:30
Replying to @mkoeppe:
Before you start designing all kinds of fancy features, I think you first want to establish a need. I don't think there is one. By the time you need micro-optimizations such as using mutable structures and in-place modification, you don't want the overhead of coercion to occur. Anyway, for a In any case, these 2-argument mutation operations do not cover what is needed for efficient mutable object manipulation. There is the three-argument version too: (I have some recent experience with inplace mutation (with mpfr) in order to get a fast evaluation of Riemann theta functions -- ticket TBA :-). If these inplace features above would have existed, I would still not have used them, because I really needed the 3-operand versions and because I wouldn't want to pay the incref/decref price for manipulating python objects. Make sure you have a usage scenario before you design the tools!) |
comment:31
Replying to @nbruin:
That's a great point, although for sparse updates of the kind ( In any case, I wouldn't expect that anyone has immediate plans to work on the mutable-update business, so we can shelve this until a need arises. |
Problem description:
Given a vector
v
with base ringR
, the constructionsw = vector(R, v)
w = vector(v, R)
w = vector(v)
all return the original vector
v
. As a consequence, all changes applied tow
are also applied tov
and vice versa.Proposal:
The
__call__
method of a parent object serves several purposes: In one-argument calls, (1) it is the identity (in the strong sense of Python'sid
) on elements of its parent and (2) in general, a convert map, with (3) input0
as a permissive special case, which is also the default argument ofParent.__call__
. (4) In multiple-argument calls, it is the element constructor.Proposal: Define a general protocol for element classes with mutability which does NOT change the above but only refines it for mutable classes as follows:
In element classes with mutability,
_element_constructor_(x, ...)
MUST support optional argumentscopy
andmutable
.These arguments are allowed to have various defaulting behavior that is the most appropriate for the specific class, but there are some restrictions:
copy
MUST NOT default toTrue
for mutable inputsx
because (as discussed) this is not compatible with (1).mutable=False
andcopy=False
MUST be an error for mutable inputx
.Moreover, arithmetic operations need to be consistent: Either always return a new element (even for trivial operations), or always return an immutable element.
We add
_test_...
methods that check this protocol.Related:
CC: @kliem @mjungmath @mkoeppe @tscrim @nbruin @dcoudert @mwageringel @pjbruin @kwankyu @williamstein
Component: misc
Keywords: vector, constructor, copy
Branch/Commit: u/mkoeppe/refined_protocol_for__element_constructor__in_element_classes_with_mutability @
501e7ef
Issue created by migration from https://trac.sagemath.org/ticket/29101
The text was updated successfully, but these errors were encountered: