473,320 Members | 1,820 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Templated identity matrix with parameterize order?

The following works:

template <typename T>
struct ID3M{
static const T ID[3][3];
};

template <typename T>
const T ID3M<T>::ID[3][3] = {{1,0,0},{0,1,0},{0,0,1}};

Is there a way to generalize this to take a parameter specifying the
order(number of elements per row)? The first part's easy:

template <typename T, unsigned ORDER>
struct IDM{
static const T ID[ORDER][ORDER];
};
But how can that be initialized to have 1's along the main diagonal and 0's
elsewhere?
--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell

Jul 22 '05 #1
9 2708
Dear Steven,

I am a little bit scared not to answer your question, and then I will get a
harsh response.
Did you think about something like this (avoiding your problem)?

template <typename T, size_t dim>
struct IDM
{

static size_t size1() { return dim; }
static size_t size2() { return dim; }

T operator[](const size_t & index1, const size_t & index2) const
{
// range checking if needed
if (index1 == index2) return 1;
else return 0;
}
};
Regards,
Patrick
Jul 22 '05 #2
Patrick Kowalzick wrote:
Dear Steven,

I am a little bit scared not to answer your question, and then I will get
a harsh response.
Did you think about something like this (avoiding your problem)?

template <typename T, size_t dim>
struct IDM
{

static size_t size1() { return dim; }
static size_t size2() { return dim; }

T operator[](const size_t & index1, const size_t & index2) const
{
// range checking if needed
if (index1 == index2) return 1;
else return 0;
}
};


Yes. I thought about it. I even wrote the code, and then realized it won't
serve my purposes. I can't pass it as an array, and I'm not sure it will
have the same performance as using an actual array. I did come up with /a/
solution. It's not my idea of elegant, but it seems to work.

Java has something called static member initialization blocks which allow
you to execute code the first time a class is loaded. I don't know if that
could be added to C++, but it sure is nice. Then again, I don't believ you
can make the members of a Java array constant. If you can access the array,
you can modify it.

This is not a finished product, just a rough draft:

/************************************************** *************************
* Copyright (C) 2004 by Steven T. Hatton *
* ha*****@globalsymmetry.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
************************************************** *************************/
#ifndef TENSOR_HH
#define TENSOR_HH
#include "sth/util/Printable_IF.hh" // ABC: print() and operator<<(&ostream)
#include "vmath_impl.hh" // namespace_name
namespace sth{
namespace vmath{
namespace {
using sth::util::Printable_IF;
using std::string;
using std::ostream;
}

template <typename T, unsigned ORDER>
class IDM{
T _m[ORDER][ORDER];
public:
typedef const T (&ref)[ORDER][ORDER];
IDM()
:ID(_m)
{
for(unsigned i = 0; i < ORDER; i++)
{
for(unsigned j = 0; j < ORDER; j++)
{
_m[i][j] = i == j ? T(1): T(0);
}
}
}
ref ID;
};
template<typename T, unsigned RANK, unsigned ORDER>
class Tensor: public Printable_IF {
public:
typedef const T (&ref)[ORDER][ORDER];
static const string class_name;
static const unsigned _RANK = RANK;
static const unsigned _ORDER = ORDER;

Tensor()
{}

virtual ostream& print(ostream& out) const;

protected:
static const ref _ID;
static const IDM<T, ORDER> _IDM;
};
template<typename T, unsigned RANK, unsigned ORDER>
const string Tensor<T, RANK, ORDER>::class_name = "Tensor<T,RANK,
ORDER>";

template<typename T, unsigned RANK, unsigned ORDER>
const IDM<T, ORDER> Tensor<T, RANK, ORDER>::_IDM = IDM<T, ORDER>();

template<typename T, unsigned RANK, unsigned ORDER>
const T (&Tensor<T, RANK, ORDER>::_ID)[ORDER][ORDER] = Tensor<T, RANK,
ORDER>::_IDM.ID;

template<typename T, unsigned RANK, unsigned ORDER>
ostream& Tensor<T, RANK, ORDER>::print(ostream& out) const
{
return out << namespace_name << "::" << class_name << "\n";
}

}
}
#endif
--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell

Jul 22 '05 #3
Steven T. Hatton wrote in news:AY********************@speakeasy.net in
comp.lang.c++:
The following works:

template <typename T>
struct ID3M{
static const T ID[3][3];
};

template <typename T>
const T ID3M<T>::ID[3][3] = {{1,0,0},{0,1,0},{0,0,1}};

Is there a way to generalize this to take a parameter specifying the
order(number of elements per row)? The first part's easy:

template <typename T, unsigned ORDER>
struct IDM{
static const T ID[ORDER][ORDER];
};
But how can that be initialized to have 1's along the main diagonal
and 0's elsewhere?


#include <iostream>

template < unsigned Order >
struct array2
{
int array[ Order ][ Order ];

typedef int const (&const_array1_t)[ Order ];

const_array1_t operator [] ( unsigned i ) const
{
return array[ i ];
}

array2()
{
for ( unsigned i = 0; i < Order; ++i )
{
for ( unsigned j = 0; j < Order; ++j )
{
array[ i ][ j ] = int( i == j );
}
}
}
};

template < unsigned Order >
struct eg
{
static array2< Order > const id;
};
template < unsigned Order>
array2< Order > const eg< Order >::id;

int main()
{
for ( unsigned i = 0; i < 4; ++i )
{
for ( unsigned j = 0; j < 4 ; ++j )
{
if ( j ) std::cout << ", ";

std::cout << eg< 4 >::id[ i ][ j ];
}
std::cout << '\n';
}
}

Note the complete lack of UPPERCASE identifier's, excepting
single character template paramiters, such things should be
reserved for preprocesor #define's, anything else is asking
for trouble.

HTH.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #4
Dear Steven,
Java has something called static member initialization blocks which allow
you to execute code the first time a class is loaded. I don't know if that could be added to C++, but it sure is nice.

Something like this? I hope it is compliant, but I think so.

#include <iostream>

struct StaticInit
{
StaticInit()
{
if ( !getinit() ) init();
}
void init()
{
std::cout << "Just called the first time...." << std::endl;
}
bool getinit() {
static bool initzed = false;
if (initzed) return true;
initzed = true;
return false;
}
};

int main()
{
{
StaticInit A;
}
StaticInit B;
return 0;
}
Jul 22 '05 #5
Better like this (a lit clearer and with possibility to init directly):

#include <iostream>

struct StaticInit
{
StaticInit()
{
static_init();
}

static void static_init()
{
static bool initzed = false;
if (!initzed)
{
initzed = true;
initcalled();
}
}

static void initcalled()
{
std::cout << "Just called the first time...." << std::endl;
}
};

int main()
{
StaticInit::static_init();
{
StaticInit A;
}
StaticInit B;
return 0;
}
Regards,
Patrick
Jul 22 '05 #6
Patrick Kowalzick wrote:
Better like this (a lit clearer and with possibility to init directly):

#include <iostream>

struct StaticInit
{
StaticInit()
{
static_init();
}

static void static_init()
{
static bool initzed = false;
if (!initzed)
{
initzed = true;
initcalled();
}
}

static void initcalled()
{
std::cout << "Just called the first time...." << std::endl;
}
};

int main()
{
StaticInit::static_init();
{
StaticInit A;
}
StaticInit B;
return 0;
}


In TC++PL(SE) (http://www.research.att.com/~bs/3rd.html) this kind of
approach is discussed. IIRC, there were some qualifications involving
dynamic linking. I'll have to think about this some more. (Or look it up.)

What I was talking about in Java is shown in this example from TJPL(3E) page
49:

class Primes {
static int[] knownPrimes = new int[4];
// static int knownPrimes[4];
static { // *static* *initialization* *block*
knownPrimes[0] = 2;
for(int i = 1; i < knownPrimes.length; i++)
//for(size_t i = 0; i < sizeof(knownPrimes)/sizeof(knownPrimes[0]);i++)
knownPrimes[i] = nextPrime();
}
// declaration of nextPrime ...
}

But, as I said, you can't make the elements of knownPrimes constant. If you
can access the array, you can change the elements.

Perhaps I could cast away constness to initialize my arrays? Is that
safe...wise?

I believe what I'm doing with the initialization at the point of definition
in the kludge I posted earlier is effectively similar to what you are
showing above. I find the syntax rather awkward, but it works.

I'm confident the CPP would provide a means of creating the nested {{{..
{0,0,...,1,0,0,...,0}...}} of arbitrary depth. I am trying very hard to
_never_ use function or object type macros. That's part of the reason I'm
working on my own vector math library. Every time I looked at the
currently available libraries, I found macros were being used. I'm trying
to determine where they are actually necessary, and what the C++ native
alternatives to the existing macros might be.
--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Russell

Jul 22 '05 #7
Rob Williscroft wrote:
#include <iostream>

template < unsigned Order >
struct array2
{
int array[ Order ][ Order ];

typedef int const (&const_array1_t)[ Order ];

const_array1_t operator [] ( unsigned i ) const
{
return array[ i ];
}

array2()
{
for ( unsigned i = 0; i < Order; ++i )
{
for ( unsigned j = 0; j < Order; ++j )
{
array[ i ][ j ] = int( i == j );
}
}
}
};

template < unsigned Order >
struct eg
{
static array2< Order > const id;
};
template < unsigned Order>
array2< Order > const eg< Order >::id;

int main()
{
for ( unsigned i = 0; i < 4; ++i )
{
for ( unsigned j = 0; j < 4 ; ++j )
{
if ( j ) std::cout << ", ";

std::cout << eg< 4 >::id[ i ][ j ];
}
std::cout << '\n';
}
}
This certainly seems close, and it has some very good ideas in it. The one
thing I believe it lacks is the ability to convert array2 to int[Order
[Order]. I'm not sure if a conversion operator can be invoked when passing
a reference to array2. I'll have to experiment.
preprocesor #define's,


With the one exception of header guards, I don't do that.
--
"If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true." - Bertrand
Russell

Jul 22 '05 #8
Steven T. Hatton <su******@setidava.kushan.aa> wrote:
serve my purposes. I can't pass it as an array, and I'm not sure it will
have the same performance as using an actual array. I did come up with /a/


You konw about expression templates (ETs)? This is the way modern LA
packages are typically implemented in C++. A matrix is not a concrete
type, but a class of types (a so-called ``concept''). This may be one
or more templates with some common properties like:

- member functions giving the number of rows and columns
- an element type
- an access operator
- ...

ET's have numerous advantages over simplistic approaches with a single
matrix type.

Cheers
-Gerhard
Jul 22 '05 #9
Dear Steven,
I'm confident the CPP would provide a means of creating the nested {{{..
{0,0,...,1,0,0,...,0}...}} of arbitrary depth. I am trying very hard to
_never_ use function or object type macros. That's part of the reason I'm
working on my own vector math library. Every time I looked at the
currently available libraries, I found macros were being used. I'm trying
to determine where they are actually necessary, and what the C++ native
alternatives to the existing macros might be.


I like macros :), but I try to avoid them as well. And I do not mind if
there are macros in the libs, espacially when I use them as a "black box".

There are quite some reasons to use macros in libraries, e.g.:
-having different versions for debugging / not debugging
-having different versions for testing / stable
-implement workarounds for non compliant compilers (nearly every one)
-repetetive code, e.g. for classes which are similar and only have semantic
differences

The rest I forgot, but I think macros are handy tools, and I do not want to
miss them.

Regards,
Patrick
Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Guenther Brunthaler | last post by:
Hi template specialists, I have a problem with the code listed below. What I wanted to do is defining an operator<< that is able to output a 'matrix<ELEMENT_T, INDEX_T>::subrange' object into...
5
by: Pete C. | last post by:
I'm trying to make a templated function a friend like this: class cls { ... friend cls func<> (const cls& a, const cls& b); }; template< template<class> class Op> cls func (const cls& a,...
3
by: Daniel L Elliott | last post by:
Hello, I want to have a class which can contain vectors of many different types (int, double, Complex, etc). Is it possible to have a generic vector inside a non-template class? Thank you,...
4
by: Michael Hopkins | last post by:
Hi all I'm trying to create compositors (as described in TCPPPL 3rd edition 22.4.7) for expressing the matrix multiplication function: mat_mult( a, b, result ); As this: result = a * b;
2
by: Alex Drummond | last post by:
Hello, Is there any way of specializing a templated function on a type which is itself templated? Here's the simplest example of the problem I can think of. Say I have written an implementation...
13
by: bevanward | last post by:
Hi All I am finding unexpected results when inserted into a newly created table that has a field of datatype int identity (1,1). Basically the order I sort on when inserting into the table is...
20
by: Frank-O | last post by:
Hi , Recently I have been commited to the task of "translating" some complex statistical algorithms from Matlab to C++. The goal is to be three times as fast as matlab ( the latest) . I've...
18
by: Hypnotik | last post by:
Hello everyone. I'm writing a program which uses a class called matrix. I have written all of the different functions, constructor, etc. When I run the program I receive "Constructor", which I...
2
by: domehead100 | last post by:
I have a templated class, CDerived: template <typename TValue, typename TDraw, typename TEdit ...> class CDerived : public CBase { TValue m_Value public: TValue& GetValue() const {
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.