00001
00012
00013 #include <boost/python.hpp>
00014
00015
00016 #ifdef HAVE_CONFIG_H
00017 #include "config.h"
00018 #endif
00019
00020 #define PY_ARRAY_UNIQUE_SYMBOL HippoPyArrayHandle
00021 #define NO_IMPORT_ARRAY
00022
00023 #include "NumArrayTuple.h"
00024
00025 #include "axes/Range.h"
00026
00027 #include "num_util.h"
00028
00029 #include <algorithm>
00030 #include <stdexcept>
00031
00032 using namespace boost::python;
00033
00034 using std::runtime_error;
00035 using std::string;
00036 using std::vector;
00037
00038 using namespace hippodraw;
00039
00040 NumArrayTuple::NumArrayTuple ()
00041 : DataSource ()
00042 {
00043 }
00044
00045 NumArrayTuple::~NumArrayTuple()
00046 {
00047 }
00048
00049 void
00050 NumArrayTuple::
00051 copy ( const DataSource & )
00052 {
00053 assert ( false );
00054 }
00055
00056 void
00057 NumArrayTuple::
00058 notifyObservers ( ) const
00059 {
00060 Observable::notifyObservers ();
00061 }
00062
00063 unsigned int
00064 NumArrayTuple::
00065 rows() const
00066 {
00067 unsigned int size = 0;
00068
00069 if ( m_data.empty () == false ) {
00070 numeric::array na = getNumArray ( 0 );
00071 size = static_cast < unsigned int > ( num_util::get_dim ( na, 0 ) );
00072 }
00073
00074 return size;
00075 }
00076
00077 bool
00078 NumArrayTuple::
00079 empty () const
00080 {
00081 return rows () == 0;
00082 }
00083
00087 double
00088 NumArrayTuple::
00089 valueAt( unsigned int row, unsigned int column ) const
00090 {
00091 #if HAVE_NUMPY || HAVE_NUMERIC
00092 PyGILState_STATE state = PyGILState_Ensure ();
00093 #endif
00094
00095 assert ( column < m_data.size () );
00096
00097 const numeric::array array = m_data[column];
00098
00099 int size = num_util::size ( array );
00100 assert ( row < static_cast < unsigned int > ( size ) );
00101
00102 object result = array[row];
00103
00104 double value = extract < double > ( result );
00105 #if HAVE_NUMPY || HAVE_NUMERIC
00106 PyGILState_Release ( state );
00107 #endif
00108
00109 return value;
00110 }
00111
00115 const std::vector < double > &
00116 NumArrayTuple::
00117 getRow ( unsigned int row ) const
00118 {
00119 unsigned int size = m_data.size();
00120 m_row.resize ( size );
00121 for ( unsigned int column = 0; column < size; column++ ) {
00122 m_row [ column ] = valueAt ( row, column );
00123 }
00124
00125 return m_row;
00126 }
00127
00130 int
00131 NumArrayTuple::
00132 addColumn ( const std::string & label,
00133 boost::python::numeric::array array )
00134 {
00135
00136 int index = indexOf ( label );
00137 if ( index >= 0 ) {
00138 string what ( "NumArrayTuple Attempt to add a column whose label, `");
00139 what += label;
00140 what += "', is same as existing column.";
00141 throw runtime_error ( what );
00142 }
00143
00144 unsigned int new_size = num_util::get_dim ( array, 0 );
00145
00146 if ( m_data.empty () == false ) {
00147 unsigned int old_size = rows ();
00148
00149 if ( old_size != 0 && old_size != new_size ) {
00150 string what ( "NumArrayTuple Attempt to add a column whose size"
00151 " is not equal to other columns." );
00152 throw runtime_error ( what );
00153 }
00154 }
00155 m_data.push_back ( array );
00156 addLabel ( label );
00157
00158 return m_data.size() - 1;
00159 }
00160
00161 void
00162 NumArrayTuple::
00163 replaceColumn ( unsigned int col,
00164 boost::python::numeric::array array )
00165 {
00166 unsigned int size = columns ();
00167 if ( col >= size ) {
00168 const string what ( "NunArrayTuple: column doesn't exist" );
00169 throw runtime_error ( what );
00170 }
00171
00172 const numeric::array old_array = m_data[col];
00173 int old_size = num_util::size ( old_array );
00174 int new_size = num_util::size ( array );
00175
00176 if ( old_size != 0 && old_size != new_size ) {
00177 const string what ( "NumArrayTuple: Attempt to replace column with one "
00178 "whose size is not equal to other columns." );
00179 throw runtime_error ( what );
00180 }
00181 m_data[col] = array;
00182
00183 notifyObservers ();
00184 }
00185
00186 void
00187 NumArrayTuple::
00188 replaceColumn ( const std::string & column,
00189 boost::python::numeric::array array )
00190 {
00191 unsigned int index = indexOf ( column );
00192
00193 replaceColumn ( index, array );
00194 }
00195
00196 numeric::array
00197 NumArrayTuple::
00198 getNumArray( unsigned int index ) const
00199 {
00200 unsigned int size = columns ();
00201 if ( index >= size ) {
00202 const string what ( "NunArrayTuple: column doesn't exist" );
00203 throw runtime_error ( what );
00204 }
00205 return m_data[index];
00206 }
00207
00208 numeric::array
00209 NumArrayTuple::
00210 getNumArray( const std::string & label ) const
00211 {
00212 unsigned int index = indexOf ( label );
00213 return getNumArray( index );
00214 }
00215
00216 void
00217 NumArrayTuple::
00218 setShape ( std::vector < unsigned int > & shape )
00219 {
00220 m_shape = shape;
00221 }
00222
00223 const vector < unsigned int > &
00224 NumArrayTuple::
00225 getShape () const
00226 {
00227 return m_shape;
00228 }
00229
00230 void
00231 NumArrayTuple::
00232 fillShape ( std::vector < intptr_t > & shape, unsigned int column ) const
00233 {
00234 shape.clear ();
00235 numeric::array na = getNumArray ( column );
00236
00237 shape = num_util::shape ( na );
00238 }
00239
00240 void
00241 NumArrayTuple::
00242 clear ()
00243 {
00244 assert ( false );
00245 }
00246
00247 void
00248 NumArrayTuple::
00249 reserve ( unsigned int )
00250 {
00251 assert ( false );
00252 }
00253
00254 double
00255 NumArrayTuple::
00256 operator [] ( std::vector < unsigned int > & ) const
00257 {
00258 assert ( false );
00259 return 0.;
00260 }