From 97f4e8f6a1ed7d1037a29b974885116619f35875 Mon Sep 17 00:00:00 2001 From: lambday Date: Wed, 29 May 2013 16:54:45 +0530 Subject: [PATCH] ptype complex64_t added --- src/shogun/base/Parameter.cpp | 114 +++++++ src/shogun/base/Parameter.h | 78 +++++ src/shogun/base/class_list.cpp.py | 7 +- src/shogun/io/HDF5File.cpp | 4 + src/shogun/io/SerializableAsciiFile.cpp | 5 + src/shogun/io/SerializableAsciiReader00.cpp | 7 + src/shogun/io/SerializableHdf5File.cpp | 1 + src/shogun/io/SerializableJsonFile.cpp | 4 + src/shogun/io/SerializableJsonReader00.cpp | 4 + src/shogun/io/SerializableXmlFile.cpp | 5 + src/shogun/io/SerializableXmlReader00.cpp | 7 + src/shogun/lib/DataType.cpp | 10 +- src/shogun/lib/DataType.h | 3 +- src/shogun/lib/SGMatrix.cpp | 58 ++++ src/shogun/lib/SGSparseMatrix.cpp | 14 +- src/shogun/lib/SGSparseVector.cpp | 12 +- src/shogun/lib/SGVector.cpp | 313 +++++++++++++++++++- src/shogun/lib/SGVector.h | 9 +- src/shogun/lib/common.h | 4 + src/shogun/mathematics/Math.h | 250 +++++++++++++++- tests/unit/lib/SGVector_unittest.cc | 72 +++++ tests/unit/mathematics/Complex_unittest.cc | 58 ++++ 22 files changed, 1028 insertions(+), 11 deletions(-) create mode 100644 tests/unit/mathematics/Complex_unittest.cc diff --git a/src/shogun/base/Parameter.cpp b/src/shogun/base/Parameter.cpp index 4daaa334663..d7cb7a848e8 100644 --- a/src/shogun/base/Parameter.cpp +++ b/src/shogun/base/Parameter.cpp @@ -112,6 +112,13 @@ Parameter::add(floatmax_t* param, const char* name, add_type(&type, param, name, description); } +void +Parameter::add(complex64_t* param, const char* name, + const char* description) { + TSGDataType type(CT_SCALAR, ST_NONE, PT_COMPLEX64); + add_type(&type, param, name, description); +} + void Parameter::add(CSGObject** param, const char* name, const char* description) { @@ -301,6 +308,13 @@ Parameter::add(SGSparseVector* param, const char* name, add_type(&type, param, name, description); } +void +Parameter::add(SGSparseVector* param, const char* name, + const char* description) { + TSGDataType type(CT_SCALAR, ST_SPARSE, PT_COMPLEX64); + add_type(&type, param, name, description); +} + /* **************************************************************** */ /* Vector wrappers */ @@ -408,6 +422,14 @@ Parameter::add_vector( add_type(&type, param, name, description); } +void +Parameter::add_vector( + complex64_t** param, index_t* length, const char* name, + const char* description) { + TSGDataType type(CT_VECTOR, ST_NONE, PT_COMPLEX64, length); + add_type(&type, param, name, description); +} + void Parameter::add_vector(CSGObject*** param, index_t* length, const char* name, const char* description) { @@ -598,6 +620,13 @@ Parameter::add_vector(SGSparseVector** param, index_t* length, add_type(&type, param, name, description); } +void +Parameter::add_vector(SGSparseVector** param, index_t* length, + const char* name, const char* description) { + TSGDataType type(CT_VECTOR, ST_SPARSE, PT_COMPLEX64, length); + add_type(&type, param, name, description); +} + @@ -692,6 +721,13 @@ void Parameter::add(SGVector* param, const char* name, add_type(&type, ¶m->vector, name, description); } +void Parameter::add(SGVector* param, const char* name, + const char* description) +{ + TSGDataType type(CT_SGVECTOR, ST_NONE, PT_COMPLEX64, ¶m->vlen); + add_type(&type, ¶m->vector, name, description); +} + void Parameter::add(SGVector* param, const char* name, const char* description) { @@ -881,6 +917,13 @@ void Parameter::add(SGVector >* param, add_type(&type, ¶m->vector, name, description); } +void Parameter::add(SGVector >* param, + const char* name, const char* description) +{ + TSGDataType type(CT_SGVECTOR, ST_SPARSE, PT_COMPLEX64, ¶m->vlen); + add_type(&type, ¶m->vector, name, description); +} + /* **************************************************************** */ /* Matrix wrappers */ @@ -1001,6 +1044,15 @@ Parameter::add_matrix( add_type(&type, param, name, description); } +void +Parameter::add_matrix( + complex64_t** param, index_t* length_y, index_t* length_x, + const char* name, const char* description) { + TSGDataType type(CT_MATRIX, ST_NONE, PT_COMPLEX64, length_y, + length_x); + add_type(&type, param, name, description); +} + void Parameter::add_matrix( CSGObject*** param, index_t* length_y, index_t* length_x, @@ -1244,6 +1296,15 @@ Parameter::add_matrix(SGSparseVector** param, add_type(&type, param, name, description); } +void +Parameter::add_matrix(SGSparseVector** param, + index_t* length_y, index_t* length_x, + const char* name, const char* description) { + TSGDataType type(CT_MATRIX, ST_SPARSE, PT_COMPLEX64, length_y, + length_x); + add_type(&type, param, name, description); +} + @@ -1351,6 +1412,14 @@ void Parameter::add(SGMatrix* param, const char* name, add_type(&type, ¶m->matrix, name, description); } +void Parameter::add(SGMatrix* param, const char* name, + const char* description) +{ + TSGDataType type(CT_SGMATRIX, ST_NONE, PT_COMPLEX64, ¶m->num_rows, + ¶m->num_cols); + add_type(&type, ¶m->matrix, name, description); +} + void Parameter::add(SGMatrix* param, const char* name, const char* description) { @@ -1566,6 +1635,14 @@ void Parameter::add(SGMatrix >* param, ¶m->num_cols); add_type(&type, ¶m->matrix, name, description); } + +void Parameter::add(SGMatrix >* param, + const char* name, const char* description) +{ + TSGDataType type(CT_SGMATRIX, ST_SPARSE, PT_COMPLEX64, ¶m->num_rows, + ¶m->num_cols); + add_type(&type, ¶m->matrix, name, description); +} /* **************************************************************** */ /* End of wrappers */ @@ -1694,6 +1771,8 @@ TParameter::delete_cont() SG_FREE(*(float64_t**) m_parameter); break; case PT_FLOATMAX: SG_FREE(*(floatmax_t**) m_parameter); break; + case PT_COMPLEX64: + SG_FREE(*(complex64_t**) m_parameter); break; case PT_SGOBJECT: CSGObject** buf = *(CSGObject***) m_parameter; @@ -1738,6 +1817,11 @@ TParameter::delete_cont() SG_FREE(*(SGString**) m_parameter); break; case PT_FLOATMAX: SG_FREE(*(SGString**) m_parameter); break; + case PT_COMPLEX64: + SG_SERROR("TParameter::delete_cont(): Implementation " + "error: Could not delete " + "String"); + break; case PT_SGOBJECT: SG_SERROR("TParameter::delete_cont(): Implementation " "error: Could not delete " @@ -1779,6 +1863,8 @@ TParameter::delete_cont() SG_FREE(*(SGSparseVector**) m_parameter); break; case PT_FLOATMAX: SG_FREE(*(SGSparseVector**) m_parameter); break; + case PT_COMPLEX64: + SG_FREE(*(SGSparseVector**) m_parameter); break; case PT_SGOBJECT: SG_SERROR("TParameter::delete_cont(): Implementation " "error: Could not delete " @@ -1847,6 +1933,9 @@ TParameter::new_cont(SGVector dims) case PT_FLOATMAX: *(floatmax_t**) m_parameter = SG_MALLOC(floatmax_t, new_length); break; + case PT_COMPLEX64: + *(complex64_t**) m_parameter + = SG_MALLOC(complex64_t, new_length); break; case PT_SGOBJECT: *(CSGObject***) m_parameter = SG_CALLOC(CSGObject*, new_length); @@ -1894,6 +1983,11 @@ TParameter::new_cont(SGVector dims) case PT_FLOATMAX: *(SGString**) m_parameter = SG_MALLOC(SGString, new_length); break; + case PT_COMPLEX64: + SG_SERROR("TParameter::new_cont(): Implementation " + "error: Could not allocate " + "String"); + break; case PT_SGOBJECT: SG_SERROR("TParameter::new_cont(): Implementation " "error: Could not allocate " @@ -1945,6 +2039,9 @@ TParameter::new_cont(SGVector dims) case PT_FLOATMAX: *(SGSparseVector**) m_parameter = SG_MALLOC(SGSparseVector, new_length); break; + case PT_COMPLEX64: + *(SGSparseVector**) m_parameter + = SG_MALLOC(SGSparseVector, new_length); break; case PT_SGOBJECT: SG_SERROR("TParameter::new_cont(): Implementation " "error: Could not allocate " @@ -3149,6 +3246,23 @@ bool TParameter::compare_ptype(EPrimitiveType ptype, void* data1, void* data2, } break; } + case PT_COMPLEX64: + { + float64_t casted1_real=((complex64_t*)data1)->real(); + float64_t casted1_imag=((complex64_t*)data1)->imag(); + float64_t casted2_real=((complex64_t*)data2)->real(); + float64_t casted2_imag=((complex64_t*)data2)->imag(); + if (CMath::abs(casted1_real-casted2_real)>accuracy || + CMath::abs(casted1_imag-casted2_imag)>accuracy) + { + SG_SDEBUG("leaving TParameter::compare_ptype(): PT_COMPLEX64: " + "data1=%f+i%f, data2=%f+i%f\n", + casted1_real, casted1_imag, + casted2_real, casted2_imag); + return false; + } + break; + } case PT_SGOBJECT: { CSGObject* casted1=*((CSGObject**)data1); diff --git a/src/shogun/base/Parameter.h b/src/shogun/base/Parameter.h index 8bee4fd91d3..a5840e96dc5 100644 --- a/src/shogun/base/Parameter.h +++ b/src/shogun/base/Parameter.h @@ -374,6 +374,13 @@ class Parameter * @param name name of parameter * @param description description of parameter */ + void add(complex64_t* param, const char* name, + const char* description=""); + /** add param + * @param param parameter itself + * @param name name of parameter + * @param description description of parameter + */ void add(CSGObject** param, const char* name, const char* description=""); /** add param @@ -558,6 +565,13 @@ class Parameter */ void add(SGSparseVector* param, const char* name, const char* description=""); + /** add param + * @param param parameter itself + * @param name name of parameter + * @param description description of parameter + */ + void add(SGSparseVector* param, const char* name, + const char* description=""); /* ************************************************************ */ /* Vector wrappers */ @@ -672,6 +686,14 @@ class Parameter * @param name name of parameter * @param description description of parameter */ + void add_vector(complex64_t** param, index_t* length, + const char* name, const char* description=""); + /** add vector param + * @param param parameter vector itself + * @param length length of vector + * @param name name of parameter + * @param description description of parameter + */ void add_vector(CSGObject*** param, index_t* length, const char* name, const char* description=""); /** add vector param @@ -882,6 +904,14 @@ class Parameter */ void add_vector(SGSparseVector** param, index_t* length, const char* name, const char* description=""); + /** add vector param + * @param param parameter vector itself + * @param length length of vector + * @param name name of parameter + * @param description description of parameter + */ + void add_vector(SGSparseVector** param, index_t* length, + const char* name, const char* description=""); /** add vector param @@ -980,6 +1010,13 @@ class Parameter * @param name name of parameter * @param description description of parameter */ + void add(SGVector* param, const char* name, + const char* description=""); + /** add vector param + * @param param parameter vector itself + * @param name name of parameter + * @param description description of parameter + */ void add(SGVector* param, const char* name, const char* description=""); /** add vector param @@ -1164,6 +1201,13 @@ class Parameter */ void add(SGVector >* param, const char* name, const char* description=""); + /** add vector param + * @param param parameter vector itself + * @param name name of parameter + * @param description description of parameter + */ + void add(SGVector >* param, + const char* name, const char* description=""); /* ************************************************************ */ /* Matrix wrappers */ @@ -1305,6 +1349,16 @@ class Parameter * @param name name of parameter * @param description description of parameter */ + void add_matrix(complex64_t** param, + index_t* length_y, index_t* length_x, + const char* name, const char* description=""); + /** add matrix param + * @param param parameter matrix itself + * @param length_y y size of matrix + * @param length_x x size of matrix + * @param name name of parameter + * @param description description of parameter + */ void add_matrix(CSGObject*** param, index_t* length_y, index_t* length_x, const char* name, const char* description=""); @@ -1568,6 +1622,16 @@ class Parameter void add_matrix(SGSparseVector** param, index_t* length_y, index_t* length_x, const char* name, const char* description=""); + /** add matrix param + * @param param parameter matrix itself + * @param length_y y size of matrix + * @param length_x x size of matrix + * @param name name of parameter + * @param description description of parameter + */ + void add_matrix(SGSparseVector** param, + index_t* length_y, index_t* length_x, + const char* name, const char* description=""); /** add matrix param * @param param parameter matrix itself * @param name name of parameter @@ -1664,6 +1728,13 @@ class Parameter * @param name name of parameter * @param description description of parameter */ + void add(SGMatrix* param, const char* name, + const char* description=""); + /** add matrix param + * @param param parameter matrix itself + * @param name name of parameter + * @param description description of parameter + */ void add(SGMatrix* param, const char* name, const char* description=""); /** add matrix param @@ -1848,6 +1919,13 @@ class Parameter */ void add(SGMatrix >* param, const char* name, const char* description=""); + /** add matrix param + * @param param parameter matrix itself + * @param name name of parameter + * @param description description of parameter + */ + void add(SGMatrix >* param, + const char* name, const char* description=""); protected: diff --git a/src/shogun/base/class_list.cpp.py b/src/shogun/base/class_list.cpp.py index 4941457e556..4ee1b6f2dae 100644 --- a/src/shogun/base/class_list.cpp.py +++ b/src/shogun/base/class_list.cpp.py @@ -10,7 +10,7 @@ class_str='class' types=["BOOL", "CHAR", "INT8", "UINT8", "INT16", "UINT16", "INT32", "UINT32", - "INT64", "UINT64", "FLOAT32", "FLOAT64", "FLOATMAX"] + "INT64", "UINT64", "FLOAT32", "FLOAT64", "FLOATMAX", "COMPLEX64"] config_tests=["HAVE_HDF5", "HAVE_JSON", "HAVE_XML", "HAVE_LAPACK", "USE_CPLEX", "USE_SVMLIGHT", "USE_GLPK", "USE_LZO", "USE_GZIP", "USE_BZIP2", "USE_LZMA", "USE_MOSEK", "HAVE_EIGEN3"] @@ -113,7 +113,10 @@ def get_template_definitions(classes): suffix='' else: suffix='_t' - d.append("\t\tcase PT_%s: return new C%s<%s%s>();\n" % (t,c,t.lower(),suffix)) + if t=='COMPLEX64': + d.append("\t\tcase PT_COMPLEX64: return NULL;\n") + else: + d.append("\t\tcase PT_%s: return new C%s<%s%s>();\n" % (t,c,t.lower(),suffix)) d.append("\t\tcase PT_SGOBJECT: return NULL;\n\t}\n\treturn NULL;\n}") definitions.append(''.join(d)) return definitions diff --git a/src/shogun/io/HDF5File.cpp b/src/shogun/io/HDF5File.cpp index 7825b784f66..53b95639fde 100644 --- a/src/shogun/io/HDF5File.cpp +++ b/src/shogun/io/HDF5File.cpp @@ -414,6 +414,10 @@ hid_t CHDF5File::get_compatible_type(H5T_class_t t_class, case PT_FLOAT32: return H5T_NATIVE_FLOAT; case PT_FLOAT64: return H5T_NATIVE_DOUBLE; case PT_FLOATMAX: return H5T_NATIVE_LDOUBLE; + case PT_COMPLEX64: + SG_ERROR("Implementation error during writing " + "HDF5File!"); + return -1; case PT_SGOBJECT: SG_ERROR("Implementation error during writing " "HDF5File!"); diff --git a/src/shogun/io/SerializableAsciiFile.cpp b/src/shogun/io/SerializableAsciiFile.cpp index cd406ed202e..cec10c68bac 100644 --- a/src/shogun/io/SerializableAsciiFile.cpp +++ b/src/shogun/io/SerializableAsciiFile.cpp @@ -152,6 +152,11 @@ CSerializableAsciiFile::write_scalar_wrapped( if (fprintf(m_fstream, "%.16Lg", *(floatmax_t*) param) <= 0) return false; break; + case PT_COMPLEX64: + if (fprintf(m_fstream, "(%.16lg,%.16lg)", + ((complex64_t*) param)->real(),((complex64_t*) param)->imag()) <= 0) + return false; + break; case PT_SGOBJECT: SG_ERROR("write_scalar_wrapped(): Implementation error during" " writing AsciiFile!"); diff --git a/src/shogun/io/SerializableAsciiReader00.cpp b/src/shogun/io/SerializableAsciiReader00.cpp index 65929428763..6a2c479d43f 100644 --- a/src/shogun/io/SerializableAsciiReader00.cpp +++ b/src/shogun/io/SerializableAsciiReader00.cpp @@ -83,6 +83,13 @@ SerializableAsciiReader00::read_scalar_wrapped( if (fscanf(m_file->m_fstream, "%Lg", (floatmax_t*) param) != 1) return false; break; + case PT_COMPLEX64: + float64_t c_real, c_imag; + if (fscanf(m_file->m_fstream, "(%lg,%lg)", &c_real, &c_imag) + != 2) return false; + ((complex64_t*) param)->real(c_real); + ((complex64_t*) param)->imag(c_imag); + break; case PT_SGOBJECT: SG_ERROR("read_scalar_wrapped(): Implementation error during" " reading AsciiFile!"); diff --git a/src/shogun/io/SerializableHdf5File.cpp b/src/shogun/io/SerializableHdf5File.cpp index caec2328cba..2318f3af8bb 100644 --- a/src/shogun/io/SerializableHdf5File.cpp +++ b/src/shogun/io/SerializableHdf5File.cpp @@ -105,6 +105,7 @@ CSerializableHdf5File::ptype2hdf5(EPrimitiveType ptype) case PT_FLOAT32: return H5T_NATIVE_FLOAT; break; case PT_FLOAT64: return H5T_NATIVE_DOUBLE; break; case PT_FLOATMAX: return H5T_NATIVE_LDOUBLE; break; + case PT_COMPLEX64: return NOT_OPEN; break; case PT_SGOBJECT: return NOT_OPEN; break; } diff --git a/src/shogun/io/SerializableJsonFile.cpp b/src/shogun/io/SerializableJsonFile.cpp index 486db7dc58b..44831a3b67c 100644 --- a/src/shogun/io/SerializableJsonFile.cpp +++ b/src/shogun/io/SerializableJsonFile.cpp @@ -191,6 +191,10 @@ CSerializableJsonFile::write_scalar_wrapped( push_object(json_object_new_double( (double) *(floatmax_t*) param)); break; + case PT_COMPLEX64: + SG_ERROR("write_scalar_wrapped(): Implementation error during" + " writing JsonFile!"); + break; case PT_SGOBJECT: SG_ERROR("write_scalar_wrapped(): Implementation error during" " writing JsonFile!"); diff --git a/src/shogun/io/SerializableJsonReader00.cpp b/src/shogun/io/SerializableJsonReader00.cpp index ab6ad4f50a8..50e459f2439 100644 --- a/src/shogun/io/SerializableJsonReader00.cpp +++ b/src/shogun/io/SerializableJsonReader00.cpp @@ -81,6 +81,10 @@ SerializableJsonReader00::read_scalar_wrapped( if (!json_object_is_type(m, json_type_double)) return false; *(floatmax_t*) param = json_object_get_double(m); break; + case PT_COMPLEX64: + SG_ERROR("write_scalar_wrapped(): Implementation error during" + " writing JsonFile!"); + break; case PT_SGOBJECT: SG_ERROR("write_scalar_wrapped(): Implementation error during" " writing JsonFile!"); diff --git a/src/shogun/io/SerializableXmlFile.cpp b/src/shogun/io/SerializableXmlFile.cpp index e1dfb08d660..09b5371f0d2 100644 --- a/src/shogun/io/SerializableXmlFile.cpp +++ b/src/shogun/io/SerializableXmlFile.cpp @@ -221,6 +221,11 @@ CSerializableXmlFile::write_scalar_wrapped( if (snprintf(buf, STRING_LEN, "%.16Lg", *(floatmax_t*) param) <= 0) return false; break; + case PT_COMPLEX64: + if (snprintf(buf, STRING_LEN, "(%.16lg,%.16lg)", + ((complex64_t*) param)->real(),((complex64_t*) param)->imag() + ) <= 0) return false; + break; case PT_SGOBJECT: SG_ERROR("write_scalar_wrapped(): Implementation error during" " writing XmlFile!"); diff --git a/src/shogun/io/SerializableXmlReader00.cpp b/src/shogun/io/SerializableXmlReader00.cpp index 7d366e47cc5..e1e8d93fe3f 100644 --- a/src/shogun/io/SerializableXmlReader00.cpp +++ b/src/shogun/io/SerializableXmlReader00.cpp @@ -91,6 +91,13 @@ SerializableXmlReader00::read_scalar_wrapped( if (sscanf(buf, "%Lg", (floatmax_t*) param) != 1) result = false; break; + case PT_COMPLEX64: + float64_t c_real, c_imag; + if (sscanf(buf, "(%lg,%lg)", &c_real, &c_imag) != 2) + result = false; + ((complex64_t*) param)->real(c_real); + ((complex64_t*) param)->imag(c_imag); + break; case PT_SGOBJECT: SG_ERROR("read_scalar_wrapped(): Implementation error during" " reading XmlFile!"); diff --git a/src/shogun/lib/DataType.cpp b/src/shogun/lib/DataType.cpp index 6923da5cbb2..ac3556bab96 100644 --- a/src/shogun/lib/DataType.cpp +++ b/src/shogun/lib/DataType.cpp @@ -165,6 +165,7 @@ TSGDataType::sizeof_stype() const case PT_FLOAT32: return sizeof (SGString); case PT_FLOAT64: return sizeof (SGString); case PT_FLOATMAX: return sizeof (SGString); + case PT_COMPLEX64: return -1; case PT_SGOBJECT: return -1; } break; @@ -183,6 +184,7 @@ TSGDataType::sizeof_stype() const case PT_FLOAT32: return sizeof (SGSparseVector); case PT_FLOAT64: return sizeof (SGSparseVector); case PT_FLOATMAX: return sizeof (SGSparseVector); + case PT_COMPLEX64: return sizeof (SGSparseVector); case PT_SGOBJECT: return -1; } break; @@ -208,6 +210,7 @@ TSGDataType::sizeof_ptype() const case PT_FLOAT32: return sizeof (float32_t); case PT_FLOAT64: return sizeof (float64_t); case PT_FLOATMAX: return sizeof (floatmax_t); + case PT_COMPLEX64: return sizeof (complex64_t); case PT_SGOBJECT: return sizeof (CSGObject*); } @@ -231,6 +234,7 @@ TSGDataType::sizeof_sparseentry(EPrimitiveType ptype) case PT_FLOAT32: return sizeof (SGSparseVectorEntry); case PT_FLOAT64: return sizeof (SGSparseVectorEntry); case PT_FLOATMAX: return sizeof (SGSparseVectorEntry); + case PT_COMPLEX64: return sizeof (SGSparseVectorEntry); case PT_SGOBJECT: return -1; } @@ -258,6 +262,7 @@ TSGDataType::offset_sparseentry(EPrimitiveType ptype) case PT_FLOAT32: result = ENTRY_OFFSET(x, float32_t); break; case PT_FLOAT64: result = ENTRY_OFFSET(x, float64_t); break; case PT_FLOATMAX: result = ENTRY_OFFSET(x, floatmax_t); break; + case PT_COMPLEX64: result = ENTRY_OFFSET(x, complex64_t); break; case PT_SGOBJECT: return -1; } @@ -306,6 +311,7 @@ TSGDataType::ptype_to_string(char* dest, EPrimitiveType ptype, case PT_FLOAT32: strncpy(p, "float32", n); break; case PT_FLOAT64: strncpy(p, "float64", n); break; case PT_FLOATMAX: strncpy(p, "floatmax", n); break; + case PT_COMPLEX64: strncpy(p, "complex64", n); break; case PT_SGOBJECT: strncpy(p, "SGSerializable*", n); break; } } @@ -339,6 +345,8 @@ TSGDataType::string_to_ptype(EPrimitiveType* ptype, const char* str) *ptype = PT_FLOAT64; return true; } if (strcmp(str, "floatmax") == 0) { *ptype = PT_FLOATMAX; return true; } + if (strcmp(str, "complex64") == 0) { + *ptype = PT_COMPLEX64; return true; } if (strcmp(str, "SGSerializable*") == 0) { *ptype = PT_SGOBJECT; return true; } @@ -347,7 +355,7 @@ TSGDataType::string_to_ptype(EPrimitiveType* ptype, const char* str) case PT_BOOL: case PT_CHAR: case PT_INT8: case PT_UINT8: case PT_INT16: case PT_UINT16: case PT_INT32: case PT_UINT32: case PT_INT64: case PT_UINT64: case PT_FLOAT32: case PT_FLOAT64: - case PT_FLOATMAX: case PT_SGOBJECT: break; + case PT_FLOATMAX: case PT_COMPLEX64: case PT_SGOBJECT: break; } return false; diff --git a/src/shogun/lib/DataType.h b/src/shogun/lib/DataType.h index 4e4480ef59e..1fb2c5795a9 100644 --- a/src/shogun/lib/DataType.h +++ b/src/shogun/lib/DataType.h @@ -55,7 +55,8 @@ enum EPrimitiveType PT_FLOAT32=10, PT_FLOAT64=11, PT_FLOATMAX=12, - PT_SGOBJECT=13 + PT_COMPLEX64=13, + PT_SGOBJECT=14 }; #endif diff --git a/src/shogun/lib/SGMatrix.cpp b/src/shogun/lib/SGMatrix.cpp index 0541de18ef1..5aaf3bb1914 100644 --- a/src/shogun/lib/SGMatrix.cpp +++ b/src/shogun/lib/SGMatrix.cpp @@ -86,6 +86,13 @@ void SGMatrix::zero() set_const(0); } +template <> +void SGMatrix::zero() +{ + if (matrix && (num_rows*num_cols)) + set_const(complex64_t(0.0)); +} + template T SGMatrix::max_single() { @@ -99,6 +106,13 @@ T SGMatrix::max_single() return max; } +template <> +complex64_t SGMatrix::max_single() +{ + SG_SERROR("SGMatrix::max_single():: Not supported for complex64_t\n"); + return complex64_t(0.0); +} + template SGMatrix SGMatrix::clone() { @@ -481,6 +495,24 @@ void SGMatrix::display_matrix( SG_SPRINT("%s]\n", prefix) } +template <> +void SGMatrix::display_matrix( + const complex64_t* matrix, int32_t rows, int32_t cols, const char* name, + const char* prefix) +{ + ASSERT(rows>=0 && cols>=0) + SG_SPRINT("%s%s=[\n", prefix, name) + for (int32_t i=0; i SGMatrix SGMatrix::create_identity_matrix(index_t size, char scale) { @@ -644,6 +676,19 @@ SGMatrix SGMatrix::create_identity_matrix(index_t size, return I; } +template <> +SGMatrix SGMatrix::create_identity_matrix(index_t size, complex64_t scale) +{ + SGMatrix I(size, size); + for (index_t i=0; i SGMatrix SGMatrix::create_centering_matrix(index_t size) @@ -884,6 +929,12 @@ void SGMatrix::load(CFile* loader) SG_RESET_LOCALE; } +template<> +void SGMatrix::load(CFile* loader) +{ + SG_SERROR("SGMatrix::load():: Not supported for complex64_t\n"); +} + template void SGMatrix::save(CFile* writer) { @@ -893,6 +944,12 @@ void SGMatrix::save(CFile* writer) SG_RESET_LOCALE; } +template<> +void SGMatrix::save(CFile* saver) +{ + SG_SERROR("SGMatrix::save():: Not supported for complex64_t\n"); +} + template SGVector SGMatrix::get_row_vector(index_t row) const { @@ -917,4 +974,5 @@ template class SGMatrix; template class SGMatrix; template class SGMatrix; template class SGMatrix; +template class SGMatrix; } diff --git a/src/shogun/lib/SGSparseMatrix.cpp b/src/shogun/lib/SGSparseMatrix.cpp index 8cd6e1d054d..5de6eb13493 100644 --- a/src/shogun/lib/SGSparseMatrix.cpp +++ b/src/shogun/lib/SGSparseMatrix.cpp @@ -50,6 +50,12 @@ void SGSparseMatrix::load(CFile* loader) SG_RESET_LOCALE; } +template<> +void SGSparseMatrix::load(CFile* loader) +{ + SG_SERROR("SGSparseMatrix::load():: Not supported for complex64_t"); +} + template void SGSparseMatrix::save(CFile* saver) { @@ -59,7 +65,12 @@ void SGSparseMatrix::save(CFile* saver) saver->set_sparse_matrix(sparse_matrix, num_features, num_vectors); SG_RESET_LOCALE; } - + +template<> +void SGSparseMatrix::save(CFile* saver) +{ + SG_SERROR("SGSparseMatrix::save():: Not supported for complex64_t"); +} template void SGSparseMatrix::copy_data(const SGReferencedData& orig) @@ -98,4 +109,5 @@ template class SGSparseMatrix; template class SGSparseMatrix; template class SGSparseMatrix; template class SGSparseMatrix; +template class SGSparseMatrix; } diff --git a/src/shogun/lib/SGSparseVector.cpp b/src/shogun/lib/SGSparseVector.cpp index 667cf472a85..89b0c05cfcf 100644 --- a/src/shogun/lib/SGSparseVector.cpp +++ b/src/shogun/lib/SGSparseVector.cpp @@ -103,9 +103,18 @@ template void SGSparseVector::save(CFile* saver) saver->set_sparse_vector(features, num_feat_entries); SG_RESET_LOCALE; } - +template <> +void SGSparseVector::load(CFile* loader) +{ + SG_SERROR("SGSparseVector::load():: Not supported for complex64_t\n"); +} +template <> +void SGSparseVector::save(CFile* saver) +{ + SG_SERROR("SGSparseVector::save():: Not supported for complex64_t\n"); +} template void SGSparseVector::copy_data(const SGReferencedData& orig) @@ -207,5 +216,6 @@ template class SGSparseVector; template class SGSparseVector; template class SGSparseVector; template class SGSparseVector; +template class SGSparseVector; } diff --git a/src/shogun/lib/SGVector.cpp b/src/shogun/lib/SGVector.cpp index be2f48cf46d..34496e0848f 100644 --- a/src/shogun/lib/SGVector.cpp +++ b/src/shogun/lib/SGVector.cpp @@ -4,11 +4,13 @@ * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * + * Written (W) 2013 Soumyajit De * Written (W) 2012 Fernando José Iglesias García * Written (W) 2010,2012 Soeren Sonnenburg * Copyright (C) 2010 Berlin Institute of Technology * Copyright (C) 2012 Soeren Sonnenburg */ + #include #include #include @@ -21,6 +23,38 @@ #include +#define COMPLEX64_ERROR_NOARG(function) \ +template <> \ +void SGVector::function() \ +{ \ + SG_SERROR("SGVector::%s():: Not supported for complex64_t\n",\ + #function);\ +} + +#define COMPLEX64_ERROR_ONEARG(function) \ +template <> \ +void SGVector::function(complex64_t a) \ +{ \ + SG_SERROR("SGVector::%s():: Not supported for complex64_t\n",\ + #function);\ +} + +#define COMPLEX64_ERROR_TWOARGS(function) \ +template <> \ +void SGVector::function(complex64_t a, complex64_t b) \ +{ \ + SG_SERROR("SGVector::%s():: Not supported for complex64_t\n",\ + #function);\ +} + +#define COMPLEX64_ERROR_THREEARGS(function) \ +template <> \ +void SGVector::function(complex64_t a, complex64_t b,\ + complex64_t c) \ +{ \ + SG_SERROR("SGVector::%s():: Not supported for complex64_t\n",\ + #function);\ +} namespace shogun { @@ -68,6 +102,13 @@ void SGVector::zero() set_const(0); } +template <> +void SGVector::zero() +{ + if (vector && vlen) + set_const(complex64_t(0.0)); +} + template void SGVector::set_const(T const_elem) { @@ -95,24 +136,32 @@ void SGVector::range_fill(T start) range_fill_vector(vector, vlen, start); } +COMPLEX64_ERROR_ONEARG(range_fill) + template void SGVector::random(T min_value, T max_value) { random_vector(vector, vlen, min_value, max_value); } +COMPLEX64_ERROR_TWOARGS(random) + template void SGVector::randperm() { randperm(vector, vlen); } +COMPLEX64_ERROR_NOARG(randperm) + template void SGVector::qsort() { CMath::qsort(vector, vlen); } +COMPLEX64_ERROR_NOARG(qsort) + /** Helper functor for the function argsort */ template struct IndexSorter @@ -143,6 +192,13 @@ SGVector SGVector::argsort() return idx; } +template <> +SGVector SGVector::argsort() +{ + SG_SERROR("SGVector::argsort():: Not supported for complex64_t\n"); + SGVector idx(vlen); + return idx; +} template index_t SGVector::find_position_to_insert(T element) @@ -156,6 +212,14 @@ index_t SGVector::find_position_to_insert(T element) return i; } +template <> +index_t SGVector::find_position_to_insert(complex64_t element) +{ + SG_SERROR("SGVector::find_position_to_insert():: \ + Not supported for complex64_t\n"); + return index_t(-1); +} + template SGVector SGVector::clone() const { @@ -184,6 +248,13 @@ void SGVector::range_fill_vector(T* vec, int32_t len, T start) vec[i]=i+start; } +template <> +void SGVector::range_fill_vector(complex64_t* vec, + int32_t len, complex64_t start) +{ + SG_SERROR("SGVector::range_fill_vector():: \ + Not supported for complex64_t\n"); +} template const T& SGVector::get_element(index_t index) @@ -443,6 +514,20 @@ void SGVector::display_vector(const floatmax_t* vector, int32_t n, SG_SPRINT("%s]\n", prefix) } +template <> +void SGVector::display_vector(const complex64_t* vector, int32_t n, + const char* name, const char* prefix) +{ + ASSERT(n>=0) + SG_SPRINT("%s%s=[", prefix, name) + for (int32_t i=0; i void SGVector::vec1_plus_scalar_times_vec2(T* vec1, const T scalar, const T* vec2, int32_t n) @@ -520,12 +605,27 @@ template vec[i]=CMath::random(min_value, max_value); } +template <> +void SGVector::random_vector(complex64_t* vec, int32_t len, + complex64_t min_value, complex64_t max_value) +{ + SG_SNOTIMPLEMENTED +} + template SGVector SGVector::randperm_vec(int32_t n) { return SGVector(randperm(n), n); } +template <> +SGVector SGVector::randperm_vec(int32_t n) +{ + SG_SNOTIMPLEMENTED + SGVector perm(n); + return perm; +} + template T* SGVector::randperm(int32_t n) { @@ -535,6 +635,14 @@ T* SGVector::randperm(int32_t n) return perm; } +template <> +complex64_t* SGVector::randperm(int32_t n) +{ + SG_SNOTIMPLEMENTED + SGVector perm(n); + return perm.vector; +} + template void SGVector::randperm(T* perm, int32_t n) { @@ -543,6 +651,11 @@ void SGVector::randperm(T* perm, int32_t n) permute(perm,n); } +template <> +void SGVector::randperm(complex64_t* perm, int32_t n) +{ + SG_SNOTIMPLEMENTED +} /** permute */ template @@ -694,6 +807,15 @@ floatmax_t SGVector::twonorm(const floatmax_t* x, int32_t len) return CMath::sqrt(result); } +template <> +complex64_t SGVector::twonorm(const complex64_t* x, int32_t len) +{ + complex64_t result(0.0); + for (int32_t i=0; i float64_t SGVector::onenorm(T* x, int32_t len) @@ -716,6 +838,13 @@ T SGVector::qsq(T* x, int32_t len, float64_t q) return result; } +template <> +complex64_t SGVector::qsq(complex64_t* x, int32_t len, float64_t q) +{ + SG_SNOTIMPLEMENTED + return complex64_t(0.0); +} + /// || x ||_q template T SGVector::qnorm(T* x, int32_t len, float64_t q) @@ -724,6 +853,13 @@ T SGVector::qnorm(T* x, int32_t len, float64_t q) return CMath::pow((float64_t) qsq(x, len, q), 1.0/q); } +template <> +complex64_t SGVector::qnorm(complex64_t* x, int32_t len, float64_t q) +{ + SG_SNOTIMPLEMENTED + return complex64_t(0.0); +} + /** @return min(vec) */ template T SGVector::min(T* vec, int32_t len) @@ -772,6 +908,13 @@ T SGVector::max_abs(T* vec, int32_t len) return maxv; } +template <> +complex64_t SGVector::max_abs(complex64_t* vec, int32_t len) +{ + SG_SNOTIMPLEMENTED + return complex64_t(0.0); +} + /** @return max(vec) */ template T SGVector::max(T* vec, int32_t len) @@ -831,6 +974,15 @@ int32_t SGVector::arg_max_abs(T * vec, int32_t inc, int32_t len, T * maxv_ptr return maxIdx; } +template <> +int32_t SGVector::arg_max_abs(complex64_t * vec, int32_t inc, + int32_t len, complex64_t * maxv_ptr) +{ + int32_t maxIdx = 0; + SG_SERROR("SGVector::arg_max_abs():: Not supported for complex64_t\n"); + return maxIdx; +} + template int32_t SGVector::arg_max(T * vec, int32_t inc, int32_t len, T * maxv_ptr) { @@ -851,6 +1003,16 @@ int32_t SGVector::arg_max(T * vec, int32_t inc, int32_t len, T * maxv_ptr) return maxIdx; } +template <> +int32_t SGVector::arg_max(complex64_t * vec, int32_t inc, + int32_t len, complex64_t * maxv_ptr) +{ + int32_t maxIdx=0; + SG_SERROR("SGVector::arg_max():: Not supported for complex64_t\n"); + return maxIdx; +} + + /// return arg_min(vec) template int32_t SGVector::arg_min(T * vec, int32_t inc, int32_t len, T * minv_ptr) @@ -872,6 +1034,15 @@ int32_t SGVector::arg_min(T * vec, int32_t inc, int32_t len, T * minv_ptr) return minIdx; } +template <> +int32_t SGVector::arg_min(complex64_t * vec, int32_t inc, + int32_t len, complex64_t * minv_ptr) +{ + int32_t minIdx=0; + SG_SERROR("SGVector::arg_min():: Not supported for complex64_t\n"); + return minIdx; +} + /// return sum(abs(vec)) template T SGVector::sum_abs(T* vec, int32_t len) @@ -922,6 +1093,14 @@ int32_t SGVector::unique(T* output, int32_t size) return j; } +template <> +int32_t SGVector::unique(complex64_t* output, int32_t size) +{ + int32_t j=0; + SG_SERROR("SGVector::unique():: Not supported for complex64_t\n"); + return j; +} + template SGVector SGVector::find(T elem) { @@ -972,6 +1151,13 @@ template float64_t SGVector::mean() const return cum/vlen; } +template <> +float64_t SGVector::mean() const +{ + SG_SNOTIMPLEMENTED + return float64_t(0.0); +} + template void SGVector::load(CFile* loader) { ASSERT(loader) @@ -986,6 +1172,12 @@ template void SGVector::load(CFile* loader) SG_RESET_LOCALE; } +template<> +void SGVector::load(CFile* loader) +{ + SG_SERROR("SGVector::load():: Not supported for complex64_t\n"); +} + template void SGVector::save(CFile* saver) { ASSERT(saver) @@ -995,6 +1187,13 @@ template void SGVector::save(CFile* saver) SG_RESET_LOCALE; } +template<> +void SGVector::save(CFile* saver) +{ + SG_SERROR("SGVector::save():: Not supported for complex64_t\n"); +} + + #define MATHOP(op) \ template void SGVector::op() \ { \ @@ -1017,13 +1216,48 @@ MATHOP(sqrt) MATHOP(tan) MATHOP(tanh) #undef MATHOP - + +#define COMPLEX64_MATHOP(op) \ +template <>\ +void SGVector::op() \ +{ \ + for (int32_t i=0; i\ +void SGVector::op() \ +{ \ + SG_SERROR("SGVector::%s():: Not supported for complex64_t\n",#op);\ +} + +COMPLEX64_MATHOP_NOTIMPLEMENTED(asin) +COMPLEX64_MATHOP_NOTIMPLEMENTED(acos) +COMPLEX64_MATHOP_NOTIMPLEMENTED(atan) +#undef COMPLEX64_MATHOP_NOTIMPLEMENTED + template void SGVector::atan2(T x) { for (int32_t i=0; i void SGVector::pow(T q) { for (int32_t i=0; i::linspace(T start, T end, int32_t n) return output; } +template <> +float64_t* SGVector::linspace(complex64_t start, complex64_t end, int32_t n) +{ + float64_t* output = SG_MALLOC(float64_t, n); + SG_SERROR("SGVector::linspace():: Not supported for complex64_t\n"); + return output; +} + +template <> +void SGVector::pow(complex64_t q) +{ + for (int32_t i=0; i SGVector SGVector::get_real() +{ + SGVector real(vlen); + for (int32_t i=0; i SGVector SGVector::get_imag() +{ + SGVector imag(vlen); + for (int32_t i=0; i \ +SGVector SGVector::function() \ +{ \ + SG_SERROR("SGVector::%s():: Not supported for %s\n", \ + #function, #type); \ + SGVector ret(vlen); \ + return ret; \ +} + +UNDEFINED(get_real, bool) +UNDEFINED(get_real, char) +UNDEFINED(get_real, int8_t) +UNDEFINED(get_real, uint8_t) +UNDEFINED(get_real, int16_t) +UNDEFINED(get_real, uint16_t) +UNDEFINED(get_real, int32_t) +UNDEFINED(get_real, uint32_t) +UNDEFINED(get_real, int64_t) +UNDEFINED(get_real, uint64_t) +UNDEFINED(get_real, float32_t) +UNDEFINED(get_real, float64_t) +UNDEFINED(get_real, floatmax_t) +UNDEFINED(get_imag, bool) +UNDEFINED(get_imag, char) +UNDEFINED(get_imag, int8_t) +UNDEFINED(get_imag, uint8_t) +UNDEFINED(get_imag, int16_t) +UNDEFINED(get_imag, uint16_t) +UNDEFINED(get_imag, int32_t) +UNDEFINED(get_imag, uint32_t) +UNDEFINED(get_imag, int64_t) +UNDEFINED(get_imag, uint64_t) +UNDEFINED(get_imag, float32_t) +UNDEFINED(get_imag, float64_t) +UNDEFINED(get_imag, floatmax_t) +#undef UNDEFINED + template class SGVector; template class SGVector; template class SGVector; @@ -1058,4 +1361,10 @@ template class SGVector; template class SGVector; template class SGVector; template class SGVector; +template class SGVector; } + +#undef COMPLEX64_ERROR_NOARG +#undef COMPLEX64_ERROR_ONEARG +#undef COMPLEX64_ERROR_TWOARGS +#undef COMPLEX64_ERROR_THREEARGS diff --git a/src/shogun/lib/SGVector.h b/src/shogun/lib/SGVector.h index 1dad4622ac1..3d6415bf9c1 100644 --- a/src/shogun/lib/SGVector.h +++ b/src/shogun/lib/SGVector.h @@ -3,7 +3,8 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. - * + * + * Written (W) 2013 Soumyajit De * Written (W) 2012 Fernando José Iglesias García * Written (W) 2010,2012 Soeren Sonnenburg * Copyright (C) 2010 Berlin Institute of Technology @@ -574,6 +575,12 @@ template class SGVector : public SGReferencedData /// hyperbolic tangent of vector elements void tanh(); + /** real part of a complex64_t vector */ + SGVector get_real(); + + /** imag part of a complex64_t vector */ + SGVector get_imag(); + protected: /** needs to be overridden to copy data */ virtual void copy_data(const SGReferencedData &orig); diff --git a/src/shogun/lib/common.h b/src/shogun/lib/common.h index 1253b634059..1dd9dee2464 100644 --- a/src/shogun/lib/common.h +++ b/src/shogun/lib/common.h @@ -59,6 +59,10 @@ typedef int machine_int_t; /** index type */ typedef int32_t index_t; +/** complex type */ +#include + +typedef std::complex complex64_t; #include #endif //__COMMON_H__ diff --git a/src/shogun/mathematics/Math.h b/src/shogun/mathematics/Math.h index a99b4e1e3b8..2cfbe077118 100644 --- a/src/shogun/mathematics/Math.h +++ b/src/shogun/mathematics/Math.h @@ -4,6 +4,7 @@ * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * + * Written (W) 2013 Soumyajit De * Written (W) 2012 Fernando José Iglesias García * Written (W) 2011 Siddharth Kherada * Written (W) 2011 Justin Patera @@ -128,6 +129,43 @@ template struct thread_qsort }; #endif // DOXYGEN_SHOULD_SKIP_THIS +#define COMPLEX64_ERROR_ONEARG(function) \ +static inline complex64_t function(complex64_t a) \ +{ \ + SG_SERROR("CMath::%s():: Not supported for complex64_t\n",\ + #function);\ + return complex64_t(0.0, 0.0); \ +} + +#define COMPLEX64_ERROR_TWOARGS(function) \ +static inline complex64_t function(complex64_t a, complex64_t b) \ +{ \ + SG_SERROR("CMath::%s():: Not supported for complex64_t\n",\ + #function);\ + return complex64_t(0.0, 0.0); \ +} + +#define COMPLEX64_ERROR_THREEARGS(function) \ +static inline complex64_t function(complex64_t a, complex64_t b, complex64_t c) \ +{ \ + SG_SERROR("CMath::%s():: Not supported for complex64_t\n",\ + #function);\ + return complex64_t(0.0, 0.0); \ +} + +#define COMPLEX64_STDMATH(function) \ +static inline complex64_t function(complex64_t a) \ +{ \ + return std::function(a); \ +} + +#define COMPLEX64_ERROR_SORT(function) \ +static void function(complex64_t* output, int32_t b) \ +{ \ + SG_SERROR("CMath::%s():: Not supported for complex64_t\n",\ + #function);\ +} + namespace shogun { /** random number generator */ @@ -160,6 +198,9 @@ class CMath : public CSGObject return (a<=b) ? a : b; } + /// min not implemented for complex64_t, returns (0.0)+i(0.0) instead + COMPLEX64_ERROR_TWOARGS(min) + ///return the maximum of two integers template static inline T max(T a, T b) @@ -167,6 +208,9 @@ class CMath : public CSGObject return (a>=b) ? a : b; } + /// max not implemented for complex64_t, returns (0.0)+i(0.0) instead + COMPLEX64_ERROR_TWOARGS(max) + ///return the value clamped to interval [lb,ub] template static inline T clamp(T value, T lb, T ub) @@ -179,6 +223,9 @@ class CMath : public CSGObject return value; } + /// clamp not implemented for complex64_t, returns (0.0)+i(0.0) instead + COMPLEX64_ERROR_THREEARGS(clamp) + ///return the absolute value of a number template static inline T abs(T a) @@ -192,6 +239,12 @@ class CMath : public CSGObject else return -a; } + + ///return the absolute value of a complex number + static inline float64_t abs(complex64_t a) + { + return std::abs(a); + } //@} /**@name misc functions */ @@ -221,6 +274,9 @@ class CMath : public CSGObject else return (a<0) ? (-1) : (+1); } + /// signum not implemented for complex64_t, returns (0.0)+i(0.0) instead + COMPLEX64_ERROR_ONEARG(sign) + /// swap e.g. floats a and b template static inline void swap(T &a,T &b) @@ -262,6 +318,9 @@ class CMath : public CSGObject #endif } + /// x^0.5, x being a complex64_t + COMPLEX64_STDMATH(sqrt) + /// x^-0.5 static inline float32_t invsqrt(float32_t x) { @@ -329,40 +388,79 @@ class CMath : public CSGObject return ::pow((double) x, (double) n); } + /// x^n, x or n being a complex64_t + static inline complex64_t pow(complex64_t x, int32_t n) + { + return std::pow(x, n); + } + + static inline complex64_t pow(complex64_t x, complex64_t n) + { + return std::pow(x, n); + } + + static inline complex64_t pow(complex64_t x, float64_t n) + { + return std::pow(x, n); + } + + static inline complex64_t pow(float64_t x, complex64_t n) + { + return std::pow(x, n); + } + static inline float64_t exp(float64_t x) { return ::exp((double) x); } + /// exp(x), x being a complex64_t + COMPLEX64_STDMATH(exp) + /** @return tangens of input */ static inline float64_t tan(float64_t x) { return ::tan((double) x); } + /// tan(x), x being a complex64_t + COMPLEX64_STDMATH(tan) + /** @return arcus tangens of input */ static inline float64_t atan(float64_t x) { return ::atan((double) x); } + /// atan(x), x being a complex64_t not implemented + COMPLEX64_ERROR_ONEARG(atan) + /** @return arcus tangens of input */ static inline float64_t atan2(float64_t x, float64_t y) { return ::atan2((double) x, (double) y); } + /// atan2(x), x being a complex64_t not implemented + COMPLEX64_ERROR_ONEARG(atan2) + /** @return tangens hyperbolicus of input */ static inline float64_t tanh(float64_t x) { return ::tanh((double) x); } + /// tanh(x), x being a complex64_t + COMPLEX64_STDMATH(tanh) + static inline float64_t log10(float64_t v) { return ::log(v)/::log(10.0); } + /// log10(x), x being a complex64_t + COMPLEX64_STDMATH(log10) + static inline float64_t log2(float64_t v) { #ifdef HAVE_LOG2 @@ -377,6 +475,9 @@ class CMath : public CSGObject return ::log(v); } + /// log(x), x being a complex64_t + COMPLEX64_STDMATH(log) + static inline index_t floor_log(index_t n) { index_t i; @@ -391,31 +492,49 @@ class CMath : public CSGObject return ::sin(x); } + /// sin(x), x being a complex64_t + COMPLEX64_STDMATH(sin) + static inline float64_t asin(float64_t x) { return ::asin(x); } + /// asin(x), x being a complex64_t not implemented + COMPLEX64_ERROR_ONEARG(asin) + static inline float64_t sinh(float64_t x) { - return ::asinh(x); + return ::asinh(x); //TODO is this correct? } + /// sinh(x), x being a complex64_t + COMPLEX64_STDMATH(sinh) + static inline float64_t cos(float64_t x) { return ::cos(x); } + /// cos(x), x being a complex64_t + COMPLEX64_STDMATH(cos) + static inline float64_t acos(float64_t x) { return ::acos(x); } + /// acos(x), x being a complex64_t not implemented + COMPLEX64_ERROR_ONEARG(acos) + static inline float64_t cosh(float64_t x) { return ::cosh(x); } + /// cosh(x), x being a complex64_t + COMPLEX64_STDMATH(cosh) + static float64_t area_under_curve(float64_t* xy, int32_t len, bool reversed) { @@ -567,6 +686,14 @@ class CMath : public CSGObject return nnz; } + static int32_t get_num_nonzero(complex64_t* vec, int32_t len) + { + int32_t nnz=0; + for (index_t i=0; i 1) qsort(&output[left],size-left); } + + /// qsort not implemented for comple64_t + COMPLEX64_ERROR_SORT(qsort) /** performs insertion sort of an array output of length size * it is sorted from in ascending (for type T) */ @@ -652,6 +782,9 @@ class CMath : public CSGObject } } + /// insertion_sort not implemented for comple64_t + COMPLEX64_ERROR_SORT(insertion_sort) + /** performs a in-place radix sort in ascending order */ template inline static void radix_sort(T* array, int32_t size) @@ -659,6 +792,9 @@ class CMath : public CSGObject radix_sort_helper(array,size,0); } + /// radix_sort not implemented for comple64_t + COMPLEX64_ERROR_SORT(radix_sort) + /* * Inline function to extract the byte at position p (from left) * of an 64 bit integer. The function is somewhat identical to @@ -670,6 +806,13 @@ class CMath : public CSGObject return (word >> (sizeof(T)-p-1) * 8) & 0xff; } + /// byte not implemented for complex64_t + static inline uint8_t byte(complex64_t word, uint16_t p) + { + SG_SERROR("CMath::byte():: Not supported for complex64_t\n"); + return uint8_t(0); + } + template static void radix_sort_helper(T* array, int32_t size, uint16_t i) { @@ -769,6 +912,12 @@ class CMath : public CSGObject } } + /// radix_sort_helper not implemented for complex64_t + static void radix_sort_helper(complex64_t* array, int32_t size, uint16_t i) + { + SG_SERROR("CMath::radix_sort_helper():: Not supported for complex64_t\n"); + } + /** Performs a quicksort on an array of pointers. * It is sorted from in ascending (for type T) * @@ -817,6 +966,12 @@ class CMath : public CSGObject qsort(&vector[left],length-left); } + /// qsort not implemented for complex64_t + static void qsort(complex64_t** vector, index_t length) + { + SG_SERROR("CMath::qsort():: Not supported for complex64_t\n"); + } + /// display bits (useful for debugging) template static void display_bits(T word, int32_t width=8*sizeof(T)) { @@ -836,6 +991,13 @@ class CMath : public CSGObject } } + /// disply_bits not implemented for complex64_t + static void display_bits(complex64_t word, + int32_t width=8*sizeof(complex64_t)) + { + SG_SERROR("CMath::display_bits():: Not supported for complex64_t\n"); + } + /** performs a quicksort on an array output of length size * it is sorted in ascending order * (for type T1) and returns the index (type T2) @@ -844,6 +1006,13 @@ class CMath : public CSGObject template static void qsort_index(T1* output, T2* index, uint32_t size); + /// qsort_index not implemented for complex64_t + template + static void qsort_index(complex64_t* output, T* index, uint32_t size) + { + SG_SERROR("CMath::qsort_index():: Not supported for complex64_t\n"); + } + /** performs a quicksort on an array output of length size * it is sorted in descending order * (for type T1) and returns the index (type T2) @@ -853,6 +1022,15 @@ class CMath : public CSGObject static void qsort_backward_index( T1* output, T2* index, int32_t size); + /// qsort_backword_index not implemented for complex64_t + template + static void qsort_backword_index( + complex64_t* output, T* index, uint32_t size) + { + SG_SERROR("CMath::qsort_backword_index():: \ + Not supported for complex64_t\n"); + } + /** performs a quicksort on an array output of length size * it is sorted in ascending order * (for type T1) and returns the index (type T2) @@ -874,6 +1052,14 @@ class CMath : public CSGObject parallel_qsort_index(&t); } + /// parallel_qsort_index not implemented for complex64_t + template + inline static void parallel_qsort_index(complex64_t* output, T* index, + uint32_t size, int32_t n_threads, int32_t limit=0) + { + SG_SERROR("CMath::parallel_qsort_index():: Not supported for complex64_t\n"); + } + template static void* parallel_qsort_index(void* p); @@ -884,12 +1070,24 @@ class CMath : public CSGObject template static void min(float64_t* output, T* index, int32_t size); + /// complex64_t cannot be used as index + static void min(float64_t* output, complex64_t* index, int32_t size) + { + SG_SERROR("CMath::min():: Not supported for complex64_t\n"); + } + /* finds the n smallest elements in output and puts these elements as the first n elements */ template static void nmin( float64_t* output, T* index, int32_t size, int32_t n); + /// complex64_t cannot be used as index + static void nmin(float64_t* output, complex64_t* index, + int32_t size, int32_t n) + { + SG_SERROR("CMath::nmin():: Not supported for complex64_t\n"); + } @@ -919,6 +1117,13 @@ class CMath : public CSGObject return start; } + /// binary_search_helper not implemented for complex64_t + static int32_t binary_search_helper(complex64_t* output, int32_t size, complex64_t elem) + { + SG_SERROR("CMath::binary_search_helper():: Not supported for complex64_t\n"); + return int32_t(0); + } + /* finds an element in a sorted array via binary search * * returns -1 if not found */ template @@ -930,6 +1135,14 @@ class CMath : public CSGObject return -1; } + /// binary_search not implemented for complex64_t + static inline int32_t binary_search(complex64_t* output, int32_t size, complex64_t elem) + { + SG_SERROR("CMath::binary_search():: Not supported for complex64_t\n"); + return int32_t(-1); + } + + /* Finds an element in a sorted array of pointers via binary search * Every element is dereferenced once before being compared * @@ -968,6 +1181,13 @@ class CMath : public CSGObject return -1; } + /// binary_search not implemented for complex64_t + static inline int32_t binary_search(complex64_t** vector, index_t length, complex64_t* elem) + { + SG_SERROR("CMath::binary_search():: Not supported for complex64_t\n"); + return int32_t(-1); + } + template static int32_t binary_search_max_lower_equal( T* output, int32_t size, T elem) @@ -981,6 +1201,15 @@ class CMath : public CSGObject return -1; } + /// binary_search_max_lower_equal not implemented for complex64_t + static int32_t binary_search_max_lower_equal(complex64_t* output, + int32_t size, complex64_t elem) + { + SG_SERROR("CMath::binary_search_max_lower_equal():: \ + Not supported for complex64_t\n"); + return int32_t(-1); + } + /// align two sequences seq1 & seq2 of length l1 and l2 using gapCost /// return alignment cost static float64_t Align( @@ -988,6 +1217,18 @@ class CMath : public CSGObject //@} + + /// returns real part of a complex64_t number + static float64_t real(complex64_t c) + { + return c.real(); + } + + /// returns imag part of a complex64_t number + static float64_t imag(complex64_t c) + { + return c.imag(); + } /// returns number generator seed inline static uint32_t get_seed() @@ -1384,4 +1625,9 @@ void CMath::min(float64_t* output, T* index, int32_t size) swap(index[0], index[min_index]); } } -#endif +#undef COMPLEX64_ERROR_ONEARG +#undef COMPLEX64_ERROR_TWOARGS +#undef COMPLEX64_ERROR_THREEARGS +#undef COMPLEX64_STDMATH +#undef COMPLEX64_ERROR_SORT +#endif /** __MATHEMATICS_H_ */ diff --git a/tests/unit/lib/SGVector_unittest.cc b/tests/unit/lib/SGVector_unittest.cc index c46f9852ff6..5673472e59c 100644 --- a/tests/unit/lib/SGVector_unittest.cc +++ b/tests/unit/lib/SGVector_unittest.cc @@ -171,3 +171,75 @@ TEST(SGVectorTest,misc) for (int32_t i = 0; i < d.vlen; ++i) EXPECT_DOUBLE_EQ(d[i],b[i]+1.3*b[i]); } + +TEST(SGVectorTest,complex64_tests) +{ + SGVector a(10); + a.set_const(complex64_t(5.0, 6.0)); + SGVector b=a.clone(); + + // test ::operator+ and [] + a=a+b; + for (index_t i=0; i::vec1_plus_scalar_times_vec2(a.vector, + complex64_t(0.0, 0.0), b.vector, a.vlen); + for (index_t i=0; i::sum_abs(a.vector, 1); + EXPECT_NEAR(sum.real(), 15.62049935181330795331, 1E-19); + EXPECT_NEAR(sum.imag(), 0.0, 1E-19); + + SGVector res=a.find(complex64_t(10.0, 12.0)); + for (index_t i=0; i::onenorm(a.vector, 1); + EXPECT_NEAR(norm1, 15.62049935181330795331, 1E-19); + + complex64_t norm2=SGVector::twonorm(a.vector, 1); + EXPECT_NEAR(norm2.real(), 10.0, 1E-19); + EXPECT_NEAR(norm2.imag(), 12.0, 1E-19); + + // tests ::maths + a.set_const(complex64_t(1.0, 2.0)); + a.abs(); + for (index_t i=0; i +#include +#include + +using namespace shogun; + +TEST(CMath, complex_test) +{ + complex64_t a(5.0, 6.0), result; + + EXPECT_NEAR(abs(a), 7.81024967590665397665, 1E-19); + result=CMath::log(a); + EXPECT_NEAR(result.real(), 2.05543693208665567695, 1E-19); + EXPECT_NEAR(result.imag(), 0.87605805059819341629, 1E-19); + result=CMath::log10(a); + EXPECT_NEAR(result.real(), 0.89266491750538345951, 1E-15); + EXPECT_NEAR(result.imag(), 0.38046717720171513433, 1E-15); + result=CMath::exp(a); + EXPECT_NEAR(result.real(), 142.50190551820736573063, 1E-13); + EXPECT_NEAR(result.imag(), -41.46893678992289267171, 1E-13); + + result=CMath::sqrt(a); + EXPECT_NEAR(result.real(), 2.53083481048315883655, 1E-19); + EXPECT_NEAR(result.imag(), 1.18537961765559618499, 1E-19); + result=CMath::pow(a, 0.25); + EXPECT_NEAR(result.real(), 1.63179612745502011784, 1E-19); + EXPECT_NEAR(result.imag(), 0.36321314829455331186, 1E-19); + + result=CMath::sin(a); + EXPECT_NEAR(result.real(), -193.43002005693958267329, 1E-19); + EXPECT_NEAR(result.imag(), 57.21839505634108746790, 1E-19); + result=CMath::sinh(a); + EXPECT_NEAR(result.real(), 71.24771797085288937978, 1E-19); + EXPECT_NEAR(result.imag(), -20.73540973837024026238, 1E-19); + + result=CMath::cos(a); + EXPECT_NEAR(result.real(), 57.21909818460073893220, 1E-19); + EXPECT_NEAR(result.imag(), 193.42764312130648818311, 1E-19); + result=CMath::cosh(a); + EXPECT_NEAR(result.real(), 71.25418754735444792914, 1E-19); + EXPECT_NEAR(result.imag(), -20.73352705155264885661, 1E-19); + + result=CMath::tan(a); + EXPECT_NEAR(result.real(), -0.00000668523139027702, 1E-19); + EXPECT_NEAR(result.imag(), 1.00001031089811975860, 1E-15); + result=CMath::tanh(a); + EXPECT_NEAR(result.real(), 0.99992337992770763400, 1E-15); + EXPECT_NEAR(result.imag(), -0.00004871701269270740, 1E-19); +}