Matrices in C++

S

Stefan Ram

More often then in my Java classes, the question is asked in
my C++ classes: »How does one define a matrix in C++?«

Well, one of the answers I give, is to use a library for
scientific computation, such as »Blitz«.

But maybe they want to see how to /implement/ a matrix in /C++/.
(I do not mean to implement using a class definition, but just
to create/read/write a matrix, and possibly do some math with it.
All without an elaborate definition of a matrix class.)

AFAIK, there is no predefined matrix type in C++. AFAIK, one
can build a matrix in several ways:

A - a two-dimensional array (not ragged) as in »double m[ 3 ][ 3 ]«,

B - a one-dimensional entity, with index »row * rowsize + col«, or

C - a one-dimensional entity of one dimensional entities (»ragged«).

In the last case, AFAIK, the most common candidates for the
type of said »entities« are arrays, ::std::vector, and ::std::array.

One also might consider mixtures :):std::vector<::std::array>)
or less common types for row/cols, such as initializer lists.

To show to beginners how to implement a matrix in C++ with
simple operations (say: read, write, add, multiply) what
of the above means of implementation should be preferred?

On the web, it seems that solution A is preferred. I think
that this has the simplest allocation of memory by just
using »double a[ 3 ][ 3 ];«. When a matrix is defined as a
::std::vector of ::std::vector it seems not to be as easy to
allocate the memory for all the rows. On the other hand,
using plain old C arrays seem to be kind of old-fashioned,
maybe there is some better way to do this in today's C++?
 
R

red floyd

More often then in my Java classes, the question is asked in
my C++ classes: »How does one define a matrix in C++?«

Well, one of the answers I give, is to use a library for
scientific computation, such as »Blitz«.

But maybe they want to see how to /implement/ a matrix in /C++/.
(I do not mean to implement using a class definition, but just
to create/read/write a matrix, and possibly do some math with it.
All without an elaborate definition of a matrix class.)
[redacted]
that this has the simplest allocation of memory by just
using »double a[ 3 ][ 3 ];«. When a matrix is defined as a
::std::vector of ::std::vector it seems not to be as easy to
allocate the memory for all the rows. On the other hand,
using plain old C arrays seem to be kind of old-fashioned,
maybe there is some better way to do this in today's C++?

Other than not reinventing the wheel, which you've discussed,
I'd go with std::array<std::array<T,M>,N> as the data type
I'd also make the data member private, and overload
operator()(int row, int col). But that's just me.
 
L

Luca Risolia

Stefan said:
More often then in my Java classes, the question is asked in
my C++ classes: »How does one define a matrix in C++?«

Well, one of the answers I give, is to use a library for
scientific computation, such as »Blitz«.

But maybe they want to see how to /implement/ a matrix in /C++/.
(I do not mean to implement using a class definition, but just
to create/read/write a matrix, and possibly do some math with it.
All without an elaborate definition of a matrix class.)

std::valarray
 
S

Stefan Ram

red floyd said:
Other than not reinventing the wheel, which you've discussed,
I'd go with std::array<std::array<T,M>,N> as the data type
I'd also make the data member private, and overload
operator()(int row, int col). But that's just me.

Does this mean that the outer array holds pointers to the
inner arrays? AFAIK, a C-array cannot be directly contained
in another C-array, and ::std::array is just a thin wrapper
around C-arrays. In this case, wouldn't this make access
more slow, because all the arrays do not necessarily sit at
one place in memory but might be distributed in different
places of memory, while a T[ N, M ] C-array is a single
region of memory and modern microprocessor architecture
prefers sequences of accesses to neighboring objects?
 
R

red floyd

red floyd said:
Other than not reinventing the wheel, which you've discussed,
I'd go with std::array<std::array<T,M>,N> as the data type
I'd also make the data member private, and overload
operator()(int row, int col). But that's just me.

Does this mean that the outer array holds pointers to the
inner arrays? AFAIK, a C-array cannot be directly contained
in another C-array, and ::std::array is just a thin wrapper
around C-arrays. In this case, wouldn't this make access
more slow, because all the arrays do not necessarily sit at
one place in memory but might be distributed in different
places of memory, while a T[ N, M ] C-array is a single
region of memory and modern microprocessor architecture
prefers sequences of accesses to neighboring objects?


No, it means the outer array has members which are arrays.
std::array is not just a "thin wrapper around C-arrays", it is
a first-class object.

Thus, if I have std::array<std::array<int,5>,6> a;

a[0] is a std::array<int 5>, not a pointer to anything.
 
Ö

Öö Tiib

red floyd said:
Other than not reinventing the wheel, which you've discussed,
I'd go with std::array<std::array<T,M>,N> as the data type
I'd also make the data member private, and overload
operator()(int row, int col). But that's just me.

Does this mean that the outer array holds pointers to the
inner arrays? AFAIK, a C-array cannot be directly contained
in another C-array, and ::std::array is just a thin wrapper
around C-arrays. In this case, wouldn't this make access
more slow, because all the arrays do not necessarily sit at
one place in memory but might be distributed in different
places of memory, while a T[ N, M ] C-array is a single
region of memory and modern microprocessor architecture
prefers sequences of accesses to neighboring objects?

'std::vector' is thin wrapper around dynamic C array.

'std::array' is thin wrapper around static C array. It
is so thin that it is required to be aggregate with specific
memory layout. That means its elements (that may be also
std::array) have to necessarily sit at adjacent places in
memory and may not be distributed in different places of
memory. IOW there can be very few reasons (and none concerning
performance) to use static C array for anything if the
implementation supports (lot more convenient to use)
'std::array'.
 
S

Stefan Ram

red floyd said:
std::array is not just a "thin wrapper around C-arrays", it is
a first-class object.

I forgot that while in C arrays can't be elements of arrays,
a struct that wraps an array can be an element of an array.
So, to make an array become an element of an array, one has to
wrap the inner array in a struct, which is one of the thing
::std::array seems to do.
 
S

Stefan Ram

Richard Damon said:
I forgot that while in C arrays can't be elements of arrays,
Not certain what you mean by C arrays can't be elements of arrays?
The definition:
char buffer[5][6];
Defines an array called "buffer" of five elements, each element being an
array of 6 characters.

Yes. My wording was wrong. I was thinking of the fact that one
cannot handle such subarrays as first-class elements of the array,
i.e., read or change them by an assignment operation. But, IIRC,
that would be possible were they wrapped in a struct.
 
S

Seungbeom Kim

Yes. My wording was wrong. I was thinking of the fact that one
cannot handle such subarrays as first-class elements of the array,
i.e., read or change them by an assignment operation. But, IIRC,
that would be possible were they wrapped in a struct.

Yes. By the way, that restriction on assignment and passing to/from
functions applies not only to subarrays that are elements of arrays
but to all arrays in general.
 
Ö

Öö Tiib

If that's your definition of "thin wrapper", then what would you
consider a "non-thin wrapper" around a dynamic array?

Standard 'std::vector' is required to be dynamic C array plus basic
set of things what one usually does with dynamic C array anyway.
Going even thinner is certainly possible (say array version of
'std::unique_ptr' or 'boost::scoped_array') but result is far
less popular. I know of no non-toy usages of 'boost::scoped_array'
so it likely borders on useless.

"Less thin" means either safety (but most undefined behavior of C
array is still in 'vector') or some sort of codec otw to data
like with 'std::vector<bool>'.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top