/* ---------------------------------------------------------------------
*
* -- Automatically Tuned Linear Algebra Software (ATLAS)
* (C) Copyright 2000 All Rights Reserved
*
* -- ATLAS routine -- Version 3.2 -- December 25, 2000
*
* Author : Antoine P. Petitet
* Originally developed at the University of Tennessee,
* Innovative Computing Laboratory, Knoxville TN, 37996-1301, USA.
*
* ---------------------------------------------------------------------
*
* -- Copyright notice and Licensing terms:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions, and the following disclaimer in
* the documentation and/or other materials provided with the distri-
* bution.
* 3. The name of the University, the ATLAS group, or the names of its
* contributors may not be used to endorse or promote products deri-
* ved from this software without specific written permission.
*
* -- Disclaimer:
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEO-
* RY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (IN-
* CLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ---------------------------------------------------------------------
*/
#ifndef ATL_REFMISC_H
#define ATL_REFMISC_H
/*
* =====================================================================
* Include files
* =====================================================================
*/
#include <math.h>
#include "atlas_enum.h"
/*
* =====================================================================
* #define macro constants
* =====================================================================
*/
#define ATL_sNONE (-1.0f)
#define ATL_sNTWO (-2.0f)
#define ATL_sONE ( 1.0f)
#define ATL_sZERO ( 0.0f)
#define ATL_dNONE (-1.0)
#define ATL_dNTWO (-2.0)
#define ATL_dONE ( 1.0)
#define ATL_dZERO ( 0.0)
/*
* =====================================================================
* # macro functions
* =====================================================================
*/
#define Msabs( a_ ) ( ( (a_) < ATL_sZERO ) ? -(a_) : (a_) )
#define Mszero( a_r_, a_i_ ) \
( ( (a_r_) == ATL_sZERO ) && ( (a_i_) == ATL_sZERO ) )
#define Msone( a_r_, a_i_ ) \
( ( (a_r_) == ATL_sONE ) && ( (a_i_) == ATL_sZERO ) )
#define Msscl( a_r_, a_i_, c_r_, c_i_ ) \
{ \
register float tmp_r_, tmp_i_; \
tmp_r_ = (a_r_) * c_r_ - (a_i_) * c_i_; \
tmp_i_ = (a_r_) * c_i_ + (a_i_) * c_r_; \
c_r_ = tmp_r_; \
c_i_ = tmp_i_; \
}
/*
* Msdiv performs complex division in real arithmetic
* a_r_ + i * a_i_ = ( a_r_ + i * a_i_ ) / ( b_r_ + i * b_i_ );
* The algorithm is due to Robert L. Smith and can be found in D. Knuth,
* The art of Computer Programming, Vol.2, p.195
*/
#define Msdiv( b_r_, b_i_, a_r_, a_i_ ) \
{ \
register float c_i_, c_r_, tmp1_, tmp2_; \
if( Msabs( b_i_ ) < Msabs( b_r_ ) ) \
{ \
tmp1_ = (b_i_) / (b_r_); \
tmp2_ = (b_r_) + (b_i_) * tmp1_; \
c_r_ = ( (a_r_) + (a_i_) * tmp1_ ) / tmp2_; \
c_i_ = ( (a_i_) - (a_r_) * tmp1_ ) / tmp2_; \
} \
else \
{ \
tmp1_ = (b_r_) / (b_i_); \
tmp2_ = (b_i_) + (b_r_) * tmp1_; \
c_r_ = ( (a_i_) + (a_r_) * tmp1_ ) / tmp2_; \
c_i_ = ( -(a_r_) + (a_i_) * tmp1_ ) / tmp2_; \
} \
a_r_ = c_r_; \
a_i_ = c_i_; \
}
#define Mdabs( a_ ) ( ( (a_) < ATL_dZERO ) ? -(a_) : (a_) )
#define Mdzero( a_r_, a_i_ ) \
( ( (a_r_) == ATL_dZERO ) && ( (a_i_) == ATL_dZERO ) )
#define Mdone( a_r_, a_i_ ) \
( ( (a_r_) == ATL_dONE ) && ( (a_i_) == ATL_dZERO ) )
#define Mdscl( a_r_, a_i_, c_r_, c_i_ ) \
{ \
register double tmp_r_, tmp_i_; \
tmp_r_ = (a_r_) * c_r_ - (a_i_) * c_i_; \
tmp_i_ = (a_r_) * c_i_ + (a_i_) * c_r_; \
c_r_ = tmp_r_; \
c_i_ = tmp_i_; \
}
/*
* Mddiv performs complex division in real arithmetic
* a_r_ + i * a_i_ = ( a_r_ + i * a_i_ ) / ( b_r_ + i * b_i_ );
* The algorithm is due to Robert L. Smith and can be found in D. Knuth,
* The art of Computer Programming, Vol.2, p.195
*/
#define Mddiv( b_r_, b_i_, a_r_, a_i_ ) \
{ \
register double c_i_, c_r_, tmp1_, tmp2_; \
if( Mdabs( b_i_ ) < Mdabs( b_r_ ) ) \
{ \
tmp1_ = (b_i_) / (b_r_); \
tmp2_ = (b_r_) + (b_i_) * tmp1_; \
c_r_ = ( (a_r_) + (a_i_) * tmp1_ ) / tmp2_; \
c_i_ = ( (a_i_) - (a_r_) * tmp1_ ) / tmp2_; \
} \
else \
{ \
tmp1_ = (b_r_) / (b_i_); \
tmp2_ = (b_i_) + (b_r_) * tmp1_; \
c_r_ = ( (a_i_) + (a_r_) * tmp1_ ) / tmp2_; \
c_i_ = ( -(a_r_) + (a_i_) * tmp1_ ) / tmp2_; \
} \
a_r_ = c_r_; \
a_i_ = c_i_; \
}
#define Mmin( a_, b_ ) ( ( (a_) < (b_) ) ? (a_) : (b_) )
#define Mmax( a_, b_ ) ( ( (a_) > (b_) ) ? (a_) : (b_) )
#define Mmul( a_r_, a_i_, b_r_, b_i_, c_r_, c_i_ ) \
{ \
c_r_ = (a_r_) * (b_r_) - (a_i_) * (b_i_); \
c_i_ = (a_r_) * (b_i_) + (a_i_) * (b_r_); \
}
#define Mmla( a_r_, a_i_, b_r_, b_i_, c_r_, c_i_ ) \
{ \
c_r_ += (a_r_) * (b_r_) - (a_i_) * (b_i_); \
c_i_ += (a_r_) * (b_i_) + (a_i_) * (b_r_); \
}
#define Mmls( a_r_, a_i_, b_r_, b_i_, c_r_, c_i_ ) \
{ \
c_r_ -= (a_r_) * (b_r_) - (a_i_) * (b_i_); \
c_i_ -= (a_r_) * (b_i_) + (a_i_) * (b_r_); \
}
#define Mset( a_r_, a_i_, b_r_, b_i_ ) \
{ \
b_r_ = (a_r_); \
b_i_ = (a_i_); \
}
#define Mselscal( al_, a_ ) \
{ \
if( (al_) == ATL_sZERO ) { (a_) = ATL_sZERO; } \
else if( (al_) != ATL_sONE ) { (a_) *= (al_); } \
}
#define Mdelscal( al_, a_ ) \
{ \
if( (al_) == ATL_dZERO ) { (a_) = ATL_dZERO; } \
else if( (al_) != ATL_dONE ) { (a_) *= (al_); } \
}
#define Mcelscal( al_r_, al_i_, a_r_, a_i_ ) \
{ \
if( Mszero( (al_r_), (al_i_) ) ) \
{ (a_r_) = (a_i_) = ATL_sZERO; } \
else if( ! Msone( (al_r_), (al_i_) ) ) \
{ Msscl( (al_r_), (al_i_), (a_r_), (a_i_) ); } \
}
#define Mzelscal( al_r_, al_i_, a_r_, a_i_ ) \
{ \
if( Mdzero( (al_r_), (al_i_) ) ) \
{ (a_r_) = (a_i_) = ATL_dZERO; } \
else if( ! Mdone( (al_r_), (al_i_) ) ) \
{ Mdscl( (al_r_), (al_i_), (a_r_), (a_i_) ); } \
}
#define Msvscal( n_, al_, x_, incx_ ) \
{ \
int i_, ix_; \
if( (al_) == ATL_sZERO ) \
{ \
for( i_ = 0, ix_ = 0; i_ < (n_); i_++, ix_ += (incx_) ) \
{ (x_)[ix_] = ATL_sZERO; } \
} \
else if( (al_) != ATL_sONE ) \
{ \
for( i_ = 0, ix_ = 0; i_ < (n_); i_++, ix_ += (incx_) ) \
{ (x_)[ix_] *= (al_); } \
} \
}
#define Mdvscal( n_, al_, x_, incx_ ) \
{ \
int i_, ix_; \
if( (al_) == ATL_dZERO ) \
{ \
for( i_ = 0, ix_ = 0; i_ < (n_); i_++, ix_ += (incx_) ) \
{ (x_)[ix_] = ATL_dZERO; } \
} \
else if( (al_) != ATL_dONE ) \
{ \
for( i_ = 0, ix_ = 0; i_ < (n_); i_++, ix_ += (incx_) ) \
{ (x_)[ix_] *= (al_); } \
} \
}
#define Mcvscal( n_, al_, x_, incx_ ) \
{ \
int i_, ix_, incx2_ = ( 2 * (incx_) ); \
if( Mszero( (al_)[0], (al_)[1] ) ) \
{ \
for( i_ = 0, ix_ = 0; i_ < (n_); i_++, ix_ += (incx2_) ) \
{ (x_)[ix_] = (x_)[ix_+1] = ATL_sZERO; } \
} \
else if( ! Msone( (al_)[0], (al_)[1] ) ) \
{ \
for( i_ = 0, ix_ = 0; i_ < (n_); i_++, ix_ += (incx2_) ) \
{ Msscl( (al_)[0], (al_)[1], (x_)[ix_], (x_)[ix_+1] ); } \
} \
}
#define Mzvscal( n_, al_, x_, incx_ ) \
{ \
int i_, ix_, incx2_ = ( 2 * (incx_) ); \
if( Mdzero( (al_)[0], (al_)[1] ) ) \
{ \
for( i_ = 0, ix_ = 0; i_ < (n_); i_++, ix_ += (incx2_) ) \
{ (x_)[ix_] = (x_)[ix_+1] = ATL_dZERO; } \
} \
else if( ! Mdone( (al_)[0], (al_)[1] ) ) \
{ \
for( i_ = 0, ix_ = 0; i_ < (n_); i_++, ix_ += (incx2_) ) \
{ Mdscl( (al_)[0], (al_)[1], (x_)[ix_], (x_)[ix_+1] ); } \
} \
}
#define Msgescal( m_, n_, al_, a_, lda_ ) \
{ \
int i_, iaij_, j_, jaj_; \
if( (al_) == ATL_sZERO ) \
{ \
for( j_ = 0, jaj_ = 0; j_ < (n_); j_++, jaj_ += (lda_) ) \
{ \
for( i_ = 0, iaij_ = jaj_; i_ < (m_); i_++, iaij_ += 1 ) \
{ (a_)[iaij_] = ATL_sZERO; } \
} \
} \
else if( (al_) != ATL_sONE ) \
{ \
for( j_ = 0, jaj_ = 0; j_ < (n_); j_++, jaj_ += (lda_) ) \
{ \
for( i_ = 0, iaij_ = jaj_; i_ < (m_); i_++, iaij_ += 1 ) \
{ (a_)[iaij_] *= (al_); } \
} \
} \
}
#define Mdgescal( m_, n_, al_, a_, lda_ ) \
{ \
int i_, iaij_, j_, jaj_; \
if( (al_) == ATL_dZERO ) \
{ \
for( j_ = 0, jaj_ = 0; j_ < (n_); j_++, jaj_ += (lda_) ) \
{ \
for( i_ = 0, iaij_ = jaj_; i_ < (m_); i_++, iaij_ += 1 ) \
{ (a_)[iaij_] = ATL_dZERO; } \
} \
} \
else if( (al_) != ATL_dONE ) \
{ \
for( j_ = 0, jaj_ = 0; j_ < (n_); j_++, jaj_ += (lda_) ) \
{ \
for( i_ = 0, iaij_ = jaj_; i_ < (m_); i_++, iaij_ += 1 ) \
{ (a_)[iaij_] *= (al_); } \
} \
} \
}
#define Mcgescal( m_, n_, al_, a_, lda_ ) \
{ \
int i_, iaij_, j_, jaj_, lda2_ = ( (lda_) << 1 ); \
if( Mszero( (al_)[0], (al_)[1] ) ) \
{ \
for( j_ = 0, jaj_ = 0; j_ < (n_); j_++, jaj_ += lda2_ ) \
{ \
for( i_ = 0, iaij_ = jaj_; i_ < (m_); i_++, iaij_ += 2 ) \
{ (a_)[iaij_] = (a_)[iaij_+1] = ATL_sZERO; } \
} \
} \
else if( ! Msone( (al_)[0], (al_)[1] ) ) \
{ \
for( j_ = 0, jaj_ = 0; j_ < (n_); j_++, jaj_ += lda2_ ) \
{ \
for( i_ = 0, iaij_ = jaj_; i_ < (m_); i_++, iaij_ += 2 ) \
{ \
Msscl( (al_)[0], (al_)[1], (a_)[iaij_], (a_)[iaij_+1] ); \
} \
} \
} \
}
#define Mzgescal( m_, n_, al_, a_, lda_ ) \
{ \
int i_, iaij_, j_, jaj_, lda2_ = ( (lda_) << 1 ); \
if( Mdzero( (al_)[0], (al_)[1] ) ) \
{ \
for( j_ = 0, jaj_ = 0; j_ < (n_); j_++, jaj_ += lda2_ ) \
{ \
for( i_ = 0, iaij_ = jaj_; i_ < (m_); i_++, iaij_ += 2 ) \
{ (a_)[iaij_] = (a_)[iaij_+1] = ATL_dZERO; } \
} \
} \
else if( ! Mdone( (al_)[0], (al_)[1] ) ) \
{ \
for( j_ = 0, jaj_ = 0; j_ < (n_); j_++, jaj_ += lda2_ ) \
{ \
for( i_ = 0, iaij_ = jaj_; i_ < (m_); i_++, iaij_ += 2 ) \
{ \
Mdscl( (al_)[0], (al_)[1], (a_)[iaij_], (a_)[iaij_+1] ); \
} \
} \
} \
}
#endif
/*
* End of atlas_refmisc.h
*/