On Sat, May 14, 2011 at 3:17 PM, Ronan Lamy <ronan.l...@gmail.com> wrote:
> Le dimanche 15 mai 2011 à 01:18 +0530, Sherjil Ozair a écrit :
>>
>>
>> On Sun, May 15, 2011 at 12:26 AM, Ronan Lamy <ronan.l...@gmail.com>
>> wrote:
>>         Le samedi 14 mai 2011 à 08:43 -0700, Vinzent Steinberg a
>>         écrit :
>>         > On 13 Mai, 01:54, SherjilOzair <sherjiloz...@gmail.com>
>>         wrote:
>>         > > Did I leave anything Vinzent ?
>>         >
>>         > I think we should also talk about the future of the matrix
>>         module (and
>>         > a possible refactoring), so that we have a clear vision of
>>         the design
>>         > when the official coding starts. For example, I'm not really
>>         happy
>>         > with the current code (everything in one file in one class)
>>         and the
>>         > current interface (A.LUsolve(b) for example).
>>
>>         Yes, having everything in one file is inconvenient.
>>
>>         For A.LUsolve(b), here's an idea. I think that it should be
>>         something
>>         like linear_solve(A, b) instead. It should be up to sympy to
>>         figure out
>>         what the best solving method is. If users want more control,
>>         they could
>>         use:
>>         >>> A_LU = A.Ludecomposition()
>>         >>> linear_solve(A_LU, b)
>>
>>
>> I don't understand the logic behind this.
>>
>>
>> Is A_LU user-usable ? For example what would print A_LU give ? How
>> does it relate to the current class structure of Sympy ? Does it
>> subclass Basic ?
>> The answer is probably 'no'.
>
> A_LU should of course be usable. It should either pretend to be Tuple(L,
> U, p) or to be the original matrix, and print and behave accordingly
> outside the context of solving linear systems.
>>
>> Why give the user something of which he has no use ?
>
> If he's asking for it, he obviously has a use for it.
>>
>> Why not a kwarg ? I think the check `if method="LU":` is as fast as
>> `if isinstance(A_LU, LUDecomposition):`.
>
> Speed is completely irrelevant here. The time taken by a call to
> isinstance() or str.__eq__() is orders of magnitudes less than the time
> it takes to solve the system. The problem of kwargs is that they
> transform a single function into a combination of as many sub-functions
> as you have valid kwarg combinations. Without kwargs, linear_solve() has
> a clear mandate: solving the system, and you're free to optimise it as
> much as you want, as you return the solution of the system. With the
> method kwarg, you lose that freedom, and are forced to use an algorithm
> that may not be optimal, or even doesn't make sense at all for some
> particular Matrix subclass - basically, you embed the implementation
> into the function signature.
>
>> What advantage does a special wrapper class just for this have ?
>
> The advantage is that you encapsulate the concept of LU decomposition,
> so that you're free to implement it like you want: as 3 ordinary
> matrices, as 2 matrices and a permutation list, sticking L and U into
> the same matrix, using dedicated structures for triangular matrices, ...
> You get to change all this without touching a single line of code
> outside the LUDecomposition class.

I can see how that would be advantageous to the developer, but to the
user, this kind of interface seems kind of awkward (much more than
keyword arguments).  I don't see why the user interface can't use
keyword arguments and those can't be mapped to objects.  That can even
be done automatically if you require the names to be the same, or the
prefix of the name to be the same. This is slightly hackish because it
requires looking up something in locals()---it's how the hints in the
ODE module work for example---but I think that it's worth it to have a
nicer user interface.  Because I really don't see what use the user
has for a LUdecomposition object other than to pass it to
linear_solve(), which just makes things two more function calls than
they need to be (this sort of "way more function calls than necessary"
is one of my biggest gripes about OO programming btw).

Aaron Meurer

>
>>         Note that I am NOT suggesting adding a method='LU' kwarg,
>>         using the LU
>>         algorithm is implicitly specified by the fact that A_LU is
>>         some kind of
>>         LUDecomposition object (probably just a wrapper around a (L,
>>         U, p)
>>         tuple). If users type 'linear_solve', they're only interested
>>         about the
>>         result. If they care about the LU decomposition, then they
>>         should get it
>>         explicitly
>>
>>         >
>>         > Ronan wrote:
>>         > > By turning naturally OO code into procedural, you lose a
>>         lot in readability
>>         > > and developer productivity.
>>         >
>>         > Well, under the hood (on the lowest level) you have some
>>         (specialized)
>>         > algorithm that operates on some data structure. I fail to
>>         see how this
>>         > is naturally OO. About abstracting between the different
>>         types of data
>>         > representation I agree, you have a point. But isn't this
>>         compatible
>>         > with such a model? You can have your OO approach on a higher
>>         level, on
>>         > the lowest level you have specialized routines (you called
>>         it "private
>>         > helpers and specialised manipulation methods") that cannot
>>         be
>>         > abstract, thus defeating the advantage of OO IMHO. Do you
>>         think it
>>         > would be better to have them inside the class rather than
>>         separated?
>>
>>         If you're thinking in terms of data structures and operations
>>         on them,
>>         then you're considering them as objects, with clear
>>         boundaries. The
>>         natural way of representing them in Python is to write a class
>>         and
>>         implement the operations as methods of that class.
>>
>>         I'm not sure what you mean about "routines that cannot be
>>         abstract", but
>>         if you're saying that it doesn't really make sense for a
>>         subclass of
>>         Matrix to have, for instance, dict manipulation methods, I
>>         tend to
>>         agree. The data structures should probably be attributes of
>>         the matrix
>>         class, rather than be the matrix class itself. So we should
>>         have:
>>
>>         class DOKMatrix(...):
>>           def __init__(self, key_dict, ...):
>>               self.dok = DOK(key_dict)
>>               ...
>>
>>           def __iadd__(self, other):
>>               ...
>>               self.dok.update(other.dok)
>>               ...
>>
>>         but not this:
>>
>>            def _update(self, dic):
>>                self.dok.update(dic)
>>
>>
>>
>>         >
>>         > > If that wasn't the case, we'd all be using
>>         > > only C - after all, it can do everything Python does,
>>         can't it?
>>         >
>>         > You could as well say that BF does everything that Python
>>         does.
>>         >
>>         > > Making high-level decisions based on micro-optimisation
>>         concerns is very
>>         > > much "premature optimisation", I think.
>>         >
>>         > I think it is not only about micro-optimization, but also
>>         about a
>>         > clear code separation. But let's hear more opinions about
>>         this.
>>         >
>>         > > The lowest level is the implementation, not the interface.
>>         The
>>         > > interface, even if it's low-level, should be designed
>>         independently.
>>         >
>>         > What do you mean? The different parts of the implementation
>>         obviously
>>         > have to interact with each other.
>>
>>         If it's only for internal use, then it's not an interface. And
>>         if it's
>>         meant to be used from the outside, then it should be designed
>>         as such.
>>         The purpose of a low-level interface is to abstract away
>>         details that
>>         happen at a lower level. So if you have an operation that
>>         combines data
>>         structures in some specified ways, you should be able to call
>>         a single
>>         function or method to do it, and it will take care of whatever
>>         tedious
>>         bookkeeping is required.
>>
>>         > > I don't think lessons learned from writing kernel code in
>>         C apply
>>         > > directly to high-level Python code.
>>         >
>>         > (IIRC his point was more general than only about kernel
>>         development.)
>>         >
>>         > > If you use a JIT (pypy) or static compilation (Cython), it
>>         shouldn't
>>         > > make any difference. If you factor in better code quality
>>         and
>>         > > productivity, OO code will actually be faster.
>>         >
>>         > You assume that OO code is always better than procedural
>>         code. I don't
>>         > think everyone agrees.
>>         >
>>         > Vinzent
>>         >
>>
>>
>>         --
>>         You received this message because you are subscribed to the
>>         Google Groups "sympy" group.
>>         To post to this group, send email to sympy@googlegroups.com.
>>         To unsubscribe from this group, send email to sympy
>>         +unsubscr...@googlegroups.com.
>>         For more options, visit this group at
>>         http://groups.google.com/group/sympy?hl=en.
>>
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "sympy" group.
>> To post to this group, send email to sympy@googlegroups.com.
>> To unsubscribe from this group, send email to sympy
>> +unsubscr...@googlegroups.com.
>> For more options, visit this group at
>> http://groups.google.com/group/sympy?hl=en.
>
>
> --
> You received this message because you are subscribed to the Google Groups 
> "sympy" group.
> To post to this group, send email to sympy@googlegroups.com.
> To unsubscribe from this group, send email to 
> sympy+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/sympy?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to sympy@googlegroups.com.
To unsubscribe from this group, send email to 
sympy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sympy?hl=en.

Reply via email to