This is the mail archive of the
gsl-discuss@sourceware.org
mailing list for the GSL project.
Re: questions about block/vector/matrix
- From: Brian Gough <bjg at gnu dot org>
- To: Gerard Jungman <jungman at cybermesa dot com>
- Cc: gsl-discuss at sourceware dot org
- Date: Fri, 16 Oct 2009 21:06:45 +0100
- Subject: Re: questions about block/vector/matrix
- References: <1254708196.18519.1.camel@ForbiddenPlanet>
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.