// os_num_complex header.
// Copyright (c) 2003-2026 Recursion Software LLC All rights reserved.
// Email: sales@recursionsw.com, psupport@recursionsw.com
// Last Modified: $Date$
#ifndef OS_MATH_NUMCOMPLEX_H
#define OS_MATH_NUMCOMPLEX_H
#include <ospace/common/throw.h>
#include <ospace/math/math_ex.h>
/**
***********************************************************
* Template Class for Numeric Complex Data.
***********************************************************
*/
template< class T >
class os_num_complex
{
public:
/**
* Constructor. Constructs a complex number with real
* and imaginary parts assigned to 0.
*/
os_num_complex();
/**
* Constructor. Constructs a
* complex number with input real and imaginary parts
* @param re real par
* @param im imaginary part
*/
os_num_complex( const T& re, const T& im );
/**
* Constructor. Constructs
* a complex number with input null-terminated string.
* @param str string of the form <real>+<imag>i, no
* white spaces
*/
os_num_complex( const char* str );
/**
* Copy constructor. Constructs a complex number with
* input complex number.
* @param cmplx complex number
*/
os_num_complex( const os_num_complex< T >& cmplx );
/**
* Access the real part of complex number.
* @return real part
*/
T real() const;
/**
* Modify the real part of complex number.
*/
void real( const T& re );
/**
* Access the imaginary part of complex number.
* @return imaginary part
*/
T imag() const;
/**
* Modify the imaginary part of complex number.
*/
void imag( const T& imag );
/**
* Dump contents of numeric complex to output stream.
* @param stream reference to output stream
*/
OS_STD_IO os_ostream& print
(
OS_STD_IO os_ostream& stream
) const;
/**
* Assignment operator.
* @param rhs input complex number
* @return reference to self
*/
os_num_complex< T >& operator=( const os_num_complex< T >& rhs );
/**
* Addition operator. Adds input complex number to
* self.
* @param rhs input complex number
* @return reference to self
*/
os_num_complex< T >& operator+=( const os_num_complex< T >& rhs );
/**
* Subtraction operator. Subtracts input complex
* number from self.
* @param rhs input complex number
* @return reference to self
*/
os_num_complex< T >& operator-=( const os_num_complex< T >& rhs );
/**
* Multiplication operator. Multiplies input complex
* number with self.
* @param rhs input complex number
* @return reference to self
*/
os_num_complex< T >& operator*=( const os_num_complex< T >& rhs );
/**
* Division operator. Divides self with input complex
* number.
* @param rhs input complex number
* @return reference to self
*/
os_num_complex< T >& operator/=( const os_num_complex< T >& rhs );
/**
* Assignment from input value. Assigns from input
* value.
* @param rhs input complex number
* @return reference to self
*/
os_num_complex< T >& operator=( const T& rhs );
/**
* Addition with input real value. Adds input
* real value to self real value. The
* imaginary value is not manipulated.
* @param rhs input real value
* @return reference to self
*/
os_num_complex< T >& operator+=( const T& rhs );
/**
* Subtraction from input real value. Subtracts input
* real value from self real value.
* The imaginary value is not manipulated.
* @param rhs input real value
* @return reference to self
*/
os_num_complex< T >& operator-=( const T& rhs );
/**
* Multiplication with input real value. Multiplies
* input real value with self real
* value. The imaginary value is not manipulated.
* @param rhs input real value
* @return reference to self
*/
os_num_complex< T >& operator*=( const T& rhs );
/**
* Division from input real value. Divides self real
* value with input real value. The
* imaginary value is not manipulated.
* @param rhs input real value
* @return reference to self
*/
os_num_complex< T >& operator/=( const T& rhs );
/**
* Equality operator. Compares the input complex
* number with self. If both real and imaginary are
* equal, returns true, else returns false.
* @param rhs input complex number
* @return true if equal, false if not
*/
bool operator==( const os_num_complex< T >& rhs ) const;
/**
* Inequality operator. Does the reverse of Equality
* operator.
* @param rhs input complex number
* @return true if equal, false if not
*/
bool operator!=( const os_num_complex< T >& rhs ) const;
private:
T m_real_;
T m_imaginary_;
};
/**
* Complex Number type with integer real and imaginary
* parts.
*/
typedef os_num_complex< int > os_int_complex;
/**
* Complex Number type with unsigned integer real and
* imaginary parts.
*/
typedef os_num_complex< unsigned int > os_uint_complex;
/**
* Complex Number type with long real and imaginary
* parts.
*/
typedef os_num_complex< long > os_long_complex;
/**
* Complex Number type with unsigned long real and
* imaginary parts.
*/
typedef os_num_complex< unsigned long > os_ulong_complex;
/**
* Complex Number type with float real and imaginary
* parts.
*/
typedef os_num_complex< float > os_float_complex;
/**
* Complex Number type with double real and imaginary
* parts.
*/
typedef os_num_complex< double > os_double_complex;
/**
* Complex Numbers addition binary operator. Adds input
* complex number with input complex number.
* @param lhs input complex number
* @param rhs input complex number
* @return complex sum of the lhs and rhs
*/
template< class T >
os_num_complex< T >
operator+( const os_num_complex< T >& lhs, const os_num_complex< T >& rhs );
/**
* Complex Numbers addition binary operator. Adds input
* complex number with input real value. The imaginary
* value is not manipulated.
* @param lhs input complex number
* @param rhs input real value
* @return complex sum of the lhs and rhs
*/
template< class T >
os_num_complex< T >
operator+( const os_num_complex< T >& lhs, const T& rhs );
/**
* Complex Numbers addition binary operator. Adds input
* real value with input complex number. The imaginary
* value is not manipulated.
* @param lhs input complex number
* @param rhs input real value
* @return complex sum of the lhs and rhs
*/
template< class T >
os_num_complex< T >
operator+( const T& lhs, const os_num_complex< T >& rhs );
/**
* Complex Numbers subtraction binary operator. Subtracts
* input complex number from input complex number.
* @param lhs input complex number
* @param rhs input complex number
* @return complex sum of the lhs and rhs
*/
template< class T >
os_num_complex< T >
operator-( const os_num_complex< T >& lhs, const os_num_complex< T >& rhs );
/**
* Complex Numbers subtraction binary operator. Subtracts
* input real value from input complex number. The
* imaginary value is not manipulated.
* @param lhs input real value
* @param rhs input complex number
* @return complex sum of the lhs and rhs
*/
template< class T >
os_num_complex< T >
operator-( const os_num_complex< T >& lhs, const T& rhs );
/**
* Complex Numbers subtraction binary operator. Subtracts
* input real value from input complex number. The
* imaginary value is not manipulated.
* @param lhs input real value
* @param rhs input complex number
* @return complex subtraction of the lhs and rhs
*/
template< class T >
os_num_complex< T >
operator-( const T& lhs, const os_num_complex< T >& rhs );
/**
* Complex Numbers multiplication binary operator.
* Multiplies input complex number with input complex number.
* @param lhs input complex number
* @param rhs input complex number
* @return complex product of the lhs and rhs
*/
template< class T >
os_num_complex< T >
operator*( const os_num_complex< T >& lhs, const os_num_complex< T >& rhs );
/**
* Complex Numbers multiplication binary operator.
* Multiplies input complex number with input real value.
* The imaginary value is not manipulated.
* @param lhs input real value
* @param rhs input complex number
* @return complex product of the lhs and rhs
*/
template< class T >
os_num_complex< T >
operator*( const os_num_complex< T >& lhs, const T& rhs );
/**
* Complex Numbers multiplication binary operator.
* Multiplies input real value with input complex number.
* The imaginary value is not manipulated.
* @param lhs input real value
* @param rhs input complex number
* @return complex product of the lhs and rhs
*/
template< class T >
os_num_complex< T >
operator*( const T& lhs, const os_num_complex< T >& rhs );
/**
* Complex Numbers division binary operator. Divides input
* complex number with input complex number.
* @param lhs input complex number
* @param rhs input complex number
* @return complex result of the division
*/
template< class T >
os_num_complex< T >
operator/( const os_num_complex< T >& lhs, const os_num_complex< T >& rhs );
/**
* Complex Numbers division binary operator. Divides input
* complex number with real value. The imaginary value is
* not manipulated.
* @param lhs input complex number
* @param rhs input real value
* @return complex result of the division
*/
template< class T >
os_num_complex< T >
operator/( const os_num_complex< T >& lhs, const T& rhs );
/**
* Complex Numbers division binary operator. Divides input
* real value with complex number. The imaginary value is
* not manipulated.
* @param lhs input real value
* @param rhs input complex number
* @return complex result of the division
*/
template< class T >
os_num_complex< T >
operator/( const T& lhs, const os_num_complex< T >& rhs );
/**
* Complex Numbers equality operator. Compares the value
* of input complex number with real value. The imaginary
* value is not manipulated.
* @param lhs input complex number
* @param rhs input real value
* @return true if equal, false otherwise
*/
template< class T >
bool
operator==( const os_num_complex< T >& lhs, const T& rhs );
/**
* Complex Numbers equality operator. Compares the input
* real value with input complex number. The imaginary
* value is not manipulated.
* @param lhs input real value
* @param rhs input complex number
* @return true if equal, false otherwise
*/
template< class T >
bool
operator==( const T& lhs, const os_num_complex< T >& rhs );
/**
* Complex Numbers inequality operator. Reverse of
* equality operator.
* @param lhs input complex number
* @param rhs input real value
* @return true if equal, false otherwise
*/
template< class T >
bool
operator!=( const os_num_complex< T >& lhs, const T& rhs );
/**
* Complex Numbers inequality operator. Reverse of
* equality operator.
* @param lhs input real value
* @param rhs input complex number
* @return true if equal, false otherwise
*/
template< class T >
bool
operator!=( const T& lhs, const os_num_complex< T >& rhs );
template< class T >
inline T
os_num_complex< T >::real() const
{
return m_real_;
}
template< class T >
inline T
os_num_complex< T >::imag() const
{
return m_imaginary_;
}
template< class T >
inline os_num_complex< T >&
os_num_complex< T >::operator+=( const os_num_complex& rhs )
{
m_real_ += rhs.real();
m_imaginary_ += rhs.imag();
return *this;
}
template< class T >
inline os_num_complex< T >&
os_num_complex< T >::operator-=( const os_num_complex& rhs )
{
m_real_ -= rhs.real();
m_imaginary_ -= rhs.imag();
return *this;
}
template< class T >
inline os_num_complex< T >&
os_num_complex< T >::operator*=( const os_num_complex& rhs )
{
//
// (a + ib) * (c + id) Real Part = (ac - bd) Complex
// Part = (a + b) * (c + d) - ac - bd
//
T l_a = rhs.real();
T l_b = rhs.imag();
T l_ac = l_a * m_real_;
T l_bd = l_b * m_imaginary_;
m_real_ = (l_ac -l_bd);
m_imaginary_ = (l_a + l_b) * (m_real_ + m_imaginary_) -l_ac -l_bd;
return *this;
}
template< class T >
inline os_num_complex< T >&
os_num_complex< T >::operator/=( const os_num_complex& rhs )
{
//
// (a + ib) / (c + id)(ac + bd)/(c^2 + d^2) + i((bc - ad) / (c^2 + d^2))
//
T l_a = m_real_;
T l_b = m_imaginary_;
T l_c = rhs.real();
T l_d = rhs.imag();
T l_csq_plus_dsq = (l_c) * (l_c) + (l_d) * (l_d);
if ( l_csq_plus_dsq == 0 )
{
OS_THROW( os_math_toolkit_error, error_div_zero, "" )
}
T l_ac_plus_bd = (l_a * l_c) + (l_b * l_d);
T l_bc_minus_ad = (l_b * l_c) -(l_a * l_d);
m_real_ = l_ac_plus_bd / l_csq_plus_dsq;
m_imaginary_ = l_bc_minus_ad / l_csq_plus_dsq;
return *this;
}
template< class T >
OS_STD_IO os_ostream&
operator<<( OS_STD_IO os_ostream& stream, const os_num_complex< T >& cmplx );
#ifdef OS_NO_AUTO_INSTANTIATE
#include <ospace/math/numcomplex.cc>
#endif
#endif // OS_MATH_NUMCOMPLEX_H