From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20519 invoked by alias); 16 Oct 2009 20:12:12 -0000 Received: (qmail 20508 invoked by uid 22791); 16 Oct 2009 20:12:11 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mail.network-theory.co.uk (HELO mail.network-theory.co.uk) (66.199.228.187) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 16 Oct 2009 20:12:05 +0000 Date: Fri, 16 Oct 2009 20:12:00 -0000 Message-ID: From: Brian Gough To: Gerard Jungman Cc: gsl-discuss@sourceware.org Subject: Re: questions about block/vector/matrix In-Reply-To: <1254708196.18519.1.camel@ForbiddenPlanet> References: <1254708196.18519.1.camel@ForbiddenPlanet> User-Agent: Wanderlust/2.14.0 (Africa) Emacs/22.2 Mule/5.0 (SAKAKI) MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII X-Message-Mac: fe3460a2a34e00a5e64f6950b828e2dc Mailing-List: contact gsl-discuss-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gsl-discuss-owner@sourceware.org X-SW-Source: 2009-q4/txt/msg00021.txt.bz2 At Sun, 04 Oct 2009 20:03:16 -0600, Gerard Jungman wrote: > > ** Specific questions/comments about blocks, vectors, matrices. > > Q1. Why do the vector and matrix structs have a block member at > all? > At first I thought it was using some block functions in the > implementation (like for i/o), but it is not. The block member > seems pointless. See the following question. As mentioned, it was to have a struct which is the same as C++ valarray. > Furthermore, from the standpoint of object design, the vector > concept does not inherit from the block concept, since a vector > is strided and a block is not. They are incompatible concepts. > If blocks have no semantic reason to be in vectors, and if they > are not used in a integral way in the implmentation, then they > should be removed. I agree, there is no inheritance relationship between them. However there is a relationship between the vector and the block if vectors are allowed to grow/shrink -- the size of the block places a limit on the maximum size on the vector. This is not something we currently use, but that is what I had in mind at the time. > Q2. What is the meaning of functions gsl_vector_alloc_from_block(), > gsl_vector_alloc_from_vector(), etc.? > gsl_vector_alloc_from_block() seems to be constructing a view > of an underlying data segment. As such, it conflicts with the > semantics of views. There should be only one view semantic. These functions create a new gsl_vector object (on the heap) referencing the same memory as an existing vector or block. Note that the gsl_vector object is only the metadata (size, stride, etc) and does not include the block of memory, just the point to it. There's a potential confusion over terminology, a gsl_vector is actually a "view" of a gsl_block (which it usually owns, but not always) and a gsl_vector_view is also a "view" - the difference is that gsl_vector is on the heap and gsl_vector_view is on the stack (and never owns the block). As discussed earlier, the version on the stack has a different type because of limitations of const (we have to define both gsl_vector_const_view and gsl_vector_view when it is on the stack whereas the heap version, as a pointer, can be used as const gsl_vector * or gsl_vector *) If there was a way to put a gsl_vector object on the stack directly without causing const violations we would not need to wrap it in a gsl_vector_view struct. > gsl_vector_alloc_from_vector() is similar, though it is more > appropriate to say it is constructing a slice of a vector. > Again, the semantics are confused. > > The suffix '_alloc' is confusing, since it is not clear what is > being alloced. Obviously the struct itself is being alloced, > since it is returned by pointer. But what about the data? Yes, it is a bit confusing. The constraint was that people should be able to write gsl_vector * v = gsl_vector_alloc(n) and have it just work, whereas it would be more logical to use gsl_block * b = gsl_block_alloc(N) gsl_vector * v = gsl_vector_view (b, stride, n) [or something like that] which is cumbersome for the typical usage. > Q3. Why do we have functions like gsl_matrix_row(), > gsl_matrix_diagonal(), etc, and yet no support for general slicing > operations? These functions should be simple wrappers over a more > general functionality. What would be the interface for a general slicing operation for the existing matrix type? I have no objection to adding it, the functions we have were added on an as-needed basis. > Q4. Why do views export a different interface? > > There are many operations on vectors that I cannot apply to > vector views, but which would make perfect sense for > views. These include obvious things like min(). max(), scale(), > etc. They also include the i/o functions. Writing and reading > from and to view objects is a perfectly well-defined notion. Maybe I have misunderstood this question but all vector and matrix operations are supported on views, by calling them as &view.vector or &view.matrix. A gsl_vector_view is a struct which contains one thing - a gsl_vector, so all operations on it are definitely supported, including i/o. Same for matrices. Without this, the views would indeed be useless.