PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.cplus > Overload = and [ ] to store complex value terms in class
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Overload = and [ ] to store complex value terms in class

Réponse
 
LinkBack Outils de la discussion
Vieux 06/04/2008, 00h11   #1
jwest
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Overload = and [ ] to store complex value terms in class


I am writing a class to wrap around a C numerical routine that processes
the real and imaginary parts of complex data in two different arrays.
The wrapper I have so far is

class COMPLEX_DATA {
std::valarray<std::complex<double> > real_data, imag_data;
public:
// (functions that call the C-code to process)
}

In order to make access to this class as transparent as possible within
our C++ code, I would like to overload equal sign and [ ] operators so
we can both read from and write to the internal valarrays directly from a
complex variable. That is, I would like to be able to do the following

COMPLEX_DATA d_c;
std::complex<double> a, b;

// Set a to the value std::complex<double>(d_c.real_data[i], d_c.imag_data[i])
// using

a = d_c[i];



// Set d_c.real_data[i] = real(b) and d_c.imag_data[i] = imag(b) using

d_c[i] = b;


The first one is easy, but the second one is unfortunately beyond my
abilities (if it is even possible). Can anyone enlighten me?
  Réponse avec citation
Vieux 06/04/2008, 03h13   #2
joe
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Overload = and [ ] to store complex value terms in class


> // Set a to the value std::complex<double>(d_c.real_data[i], d_c.imag_data[i])
> // using
>
> a = d_c[i];
>
> // Set d_c.real_data[i] = real(b) and d_c.imag_data[i] = imag(b) using
>
> d_c[i] = b;
>
> The first one is easy, but the second one is unfortunately beyond my
> abilities (if it is even possible). Can anyone enlighten me?


My first instinct would to expose the fact that you have separate R/I
data by having member functions

d_c.real(i) = b.real();
d_c.imag(i) = b.imag();

But I guess you could do something a lot more complicated like define
the following in class COMPLEX_DATA:

somethingElse& operator[](unsigned index)
{
SomethingElse* se = new SomethingElse; //use your favorite smart
pointer
se.index = index;
se.parent = this;
return *se;
}

and add
friend SomethingElse;

and add the following:

class SomethingElse
{
public:
std::complex<double>& operator==(std::complex<double>& num)
{
parent->real_data[index] = num.real();
parent->imag_data[index] = num.imag();
return num;
}

private:
unsigned index;
COMPLEX_DATA* parent;

};


  Réponse avec citation
Vieux 06/04/2008, 03h14   #3
Gianni Mariani
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Overload = and [ ] to store complex value terms in class

jwest wrote:
> I am writing a class to wrap around a C numerical routine that processes
> the real and imaginary parts of complex data in two different arrays.
> The wrapper I have so far is
>
> class COMPLEX_DATA {
> std::valarray<std::complex<double> > real_data, imag_data;

I assume you really mean
std::valarray<double> real_data, imag_data;
> public:
> // (functions that call the C-code to process)
> }
>
> In order to make access to this class as transparent as possible within
> our C++ code, I would like to overload equal sign and [ ] operators so
> we can both read from and write to the internal valarrays directly from a
> complex variable. That is, I would like to be able to do the following
>
> COMPLEX_DATA d_c;
> std::complex<double> a, b;
>
> // Set a to the value std::complex<double>(d_c.real_data[i], d_c.imag_data[i])
> // using
>
> a = d_c[i];
>
>
>
> // Set d_c.real_data[i] = real(b) and d_c.imag_data[i] = imag(b) using
>
> d_c[i] = b;
>
>
> The first one is easy, but the second one is unfortunately beyond my
> abilities (if it is even possible). Can anyone enlighten me?


OK - here is an example using a proxy class.

#include <complex>
#include <valarray>

class COMPLEX_DATA {
std::valarray<double> real_data, imag_data;
public:

COMPLEX_DATA(std::size_t size)
: real_data(size), imag_data(size)
{}

class adaptor {
COMPLEX_DATA & v;
const std::size_t index;

public:
adaptor( COMPLEX_DATA & v, std::size_t index )
: v(v), index(index) {}

adaptor & operator = ( const std::complex<double> & val ) const
{
v.real_data[index] = val.real();
v.imag_data[index] = val.imag();
}

operator std::complex<double> () const
{
return std::complex<double>(
v.real_data[index], v.imag_data[index] );
}
};

const std::complex<double> operator[](std::size_t index) const
{
return std::complex<double>( real_data[index], imag_data[index]);
}

const adaptor operator[](std::size_t index)
{
return adaptor(*this, index);
}
};

void f(COMPLEX_DATA & d)
{
std::complex<double> v(1,1);

d[2] = v;

v = d[2];
}

void y(const COMPLEX_DATA & d)
{
std::complex<double> v(1,1);

// d[2] = v; -- error - can't assign to const

v = d[2];
}

COMPLEX_DATA d(std::size_t(30));

int main()
{
f(d);
y(d);
}
  Réponse avec citation
Vieux 06/04/2008, 03h23   #4
joe
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Overload = and [ ] to store complex value terms in class


> adaptor & operator = ( const std::complex<double> & val ) const
> {
> v.real_data[index] = val.real();
> v.imag_data[index] = val.imag();


---> return *this;


> }
>


This example is well more thought out than mine. (Disregard mine in
favor of Gianni's version). Except for the above correction; although
I think I prefer the adapter's operator just to return 'val'
  Réponse avec citation
Vieux 06/04/2008, 03h27   #5
joe
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Overload = and [ ] to store complex value terms in class

On Apr 5, 10:23 pm, joe <joeyc...@mail.com> wrote:
> > adaptor & operator = ( const std::complex<double> & val ) const
> > {
> > v.real_data[index] = val.real();
> > v.imag_data[index] = val.imag();

>
> ---> return *this;
>
> > }

>
> This example is well more thought out than mine. (Disregard mine in
> favor of Gianni's version). Except for the above correction; although
> I think I prefer the adapter's operator just to return 'val'


....And I believe that adapter will still need to be a friend of
COMPLEX_DATA to access "real_data" in the above example, although I
suspect you should/will/do have public member functions to access
these individually.
  Réponse avec citation
Vieux 06/04/2008, 08h46   #6
Gianni Mariani
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Overload = and [ ] to store complex value terms in class

joe wrote:
> On Apr 5, 10:23 pm, joe <joeyc...@mail.com> wrote:
>>> adaptor & operator = ( const std::complex<double> & val ) const
>>> {
>>> v.real_data[index] = val.real();
>>> v.imag_data[index] = val.imag();

>> ---> return *this;
>>
>>> }

>> This example is well more thought out than mine. (Disregard mine in
>> favor of Gianni's version). Except for the above correction; although
>> I think I prefer the adapter's operator just to return 'val'



I compiled it ... honest - I prolly shoulda turned warnings on.

>
> ...And I believe that adapter will still need to be a friend of
> COMPLEX_DATA to access "real_data" in the above example, although I
> suspect you should/will/do have public member functions to access
> these individually.


An inner class has visibility into it's outer class.

As for the return value of operator=, I'm thinking you don't want
someone to expect code like this to break:

(v = A) = C;

... yep, it's an edge case but it comes in hidden ways when you pass
parameters - especially template based ones.
  Réponse avec citation
Vieux 06/04/2008, 20h39   #7
jwest
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Overload = and [ ] to store complex value terms in class

On 2008-04-06, joe <joeycook@mail.com> wrote:
>
>> adaptor & operator = ( const std::complex<double> & val ) const
>> {
>> v.real_data[index] = val.real();
>> v.imag_data[index] = val.imag();

>
> ---> return *this;
>
>
>> }
>>

>
> This example is well more thought out than mine. (Disregard mine in
> favor of Gianni's version). Except for the above correction; although
> I think I prefer the adapter's operator just to return 'val'


I'll change a statement in my OP a bit. This wasn't beyond my ability,
this was WAY beyond my ability . Thank you both very much. I'll get it
implemented in the code with a citation to your posts on Google. The
class will primarily be used by engineering students with most of their
programming experience in Matlab, so I'm pretty confident that making
access look as much like access to a standard array/vector will ultimately
save us a lot of time in the future.
  Réponse avec citation
Vieux 06/04/2008, 21h48   #8
Gianni Mariani
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Overload = and [ ] to store complex value terms in class

jwest wrote:
> On 2008-04-06, joe <joeycook@mail.com> wrote:
>>> adaptor & operator = ( const std::complex<double> & val ) const
>>> {
>>> v.real_data[index] = val.real();
>>> v.imag_data[index] = val.imag();

>> ---> return *this;
>>
>>
>>> }
>>>

>> This example is well more thought out than mine. (Disregard mine in
>> favor of Gianni's version). Except for the above correction; although
>> I think I prefer the adapter's operator just to return 'val'

>
> I'll change a statement in my OP a bit. This wasn't beyond my ability,
> this was WAY beyond my ability . Thank you both very much. I'll get it
> implemented in the code with a citation to your posts on Google. The
> class will primarily be used by engineering students with most of their
> programming experience in Matlab, so I'm pretty confident that making
> access look as much like access to a standard array/vector will ultimately
> save us a lot of time in the future.


I just took another squiz at the code - I left out an explicit on the
constructor as well.

You can also add "iterator" support to this which would then make it
work with many of the standard algorithms as well.

#include <complex>
#include <valarray>

class COMPLEX_DATA {
std::valarray<double> real_data, imag_data;
public:

explicit COMPLEX_DATA(std::size_t size)
: real_data(size), imag_data(size)
{}

class adaptor {
COMPLEX_DATA & v;
const std::size_t index;

public:
adaptor( COMPLEX_DATA & v, std::size_t index )
: v(v), index(index) {}

const adaptor &operator=(const std::complex<double> & val) const
{
v.real_data[index] = val.real();
v.imag_data[index] = val.imag();
return * this;
}

operator std::complex<double> () const
{
return std::complex<double>(
v.real_data[index], v.imag_data[index] );
}
};

const std::complex<double> operator[](std::size_t index) const
{
return std::complex<double>(
real_data[index], imag_data[index] );
}

const adaptor operator[](std::size_t index)
{
return adaptor(*this, index);
}
};

// "compile" test code

void f(COMPLEX_DATA & d)
{
std::complex<double> v(1,1);

d[2] = v;

v = d[2];
}

void y(const COMPLEX_DATA & d)
{
std::complex<double> v(1,1);

// d[2] = v; -- error - can't assign to const

v = d[2];
}

COMPLEX_DATA d(30);

int main()
{
f(d);
y(d);

std::complex<double> v(1,1);
std::complex<double> u(2,1);
(d[3]=u)=v;
}
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 12h27.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,22545 seconds with 16 queries