SHOGUN
v3.2.0
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 3 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * Written (W) 2013 Heiko Strathmann 00008 */ 00009 00010 #include <shogun/features/streaming/generators/GaussianBlobsDataGenerator.h> 00011 00012 using namespace shogun; 00013 00014 CGaussianBlobsDataGenerator::CGaussianBlobsDataGenerator() : 00015 CStreamingDenseFeatures<float64_t>() 00016 { 00017 init(); 00018 } 00019 00020 CGaussianBlobsDataGenerator::CGaussianBlobsDataGenerator(index_t sqrt_num_blobs, 00021 float64_t distance, float64_t stretch, float64_t angle) : 00022 CStreamingDenseFeatures<float64_t>() 00023 { 00024 init(); 00025 set_blobs_model(sqrt_num_blobs, distance, stretch, angle); 00026 } 00027 00028 CGaussianBlobsDataGenerator::~CGaussianBlobsDataGenerator() 00029 { 00030 } 00031 00032 void CGaussianBlobsDataGenerator::set_blobs_model(index_t sqrt_num_blobs, 00033 float64_t distance, float64_t stretch, float64_t angle) 00034 { 00035 m_sqrt_num_blobs=sqrt_num_blobs; 00036 m_distance=distance; 00037 m_stretch=stretch; 00038 m_angle=angle; 00039 00040 /* precompute cholesky decomposition, start with rotation matrix */ 00041 SGMatrix<float64_t> R(2, 2); 00042 R(0, 0)=CMath::cos(angle); 00043 R(0, 1)=-CMath::sin(angle); 00044 R(1, 0)=CMath::sin(angle); 00045 R(1, 1)=CMath::cos(angle); 00046 00047 /* diagonal eigenvalue matrix */ 00048 SGMatrix<float64_t> L(2, 2); 00049 L(0, 0)=CMath::sqrt(stretch); 00050 L(1, 0)=0; 00051 L(0, 1)=0; 00052 L(1, 1)=1; 00053 00054 /* compute and save cholesky for sampling later on */ 00055 m_cholesky=SGMatrix<float64_t>::matrix_multiply(R, L); 00056 } 00057 00058 void CGaussianBlobsDataGenerator::init() 00059 { 00060 SG_ADD(&m_sqrt_num_blobs, "sqrt_num_blobs", "Number of Blobs per row", 00061 MS_NOT_AVAILABLE); 00062 SG_ADD(&m_distance, "distance", "Distance between blobs", 00063 MS_NOT_AVAILABLE); 00064 SG_ADD(&m_stretch, "stretch", "Stretch of blobs", 00065 MS_NOT_AVAILABLE); 00066 SG_ADD(&m_angle, "angle", "Angle of Blobs", 00067 MS_NOT_AVAILABLE); 00068 SG_ADD(&m_cholesky, "cholesky", "Cholesky factor of covariance matrix", 00069 MS_NOT_AVAILABLE); 00070 00071 m_sqrt_num_blobs=1; 00072 m_distance=0; 00073 m_stretch=1; 00074 m_angle=0; 00075 m_cholesky=SGMatrix<float64_t>(2, 2); 00076 m_cholesky(0, 0)=1; 00077 m_cholesky(0, 1)=0; 00078 m_cholesky(1, 0)=0; 00079 m_cholesky(1, 1)=1; 00080 00081 unset_generic(); 00082 } 00083 00084 bool CGaussianBlobsDataGenerator::get_next_example() 00085 { 00086 SG_SDEBUG("entering CGaussianBlobsDataGenerator::get_next_example()\n"); 00087 00088 /* allocate space */ 00089 SGVector<float64_t> result=SGVector<float64_t>(2); 00090 00091 /* sample latent distribution to compute offsets */ 00092 index_t x_offset=CMath::random(0, m_sqrt_num_blobs-1)*m_distance; 00093 index_t y_offset=CMath::random(0, m_sqrt_num_blobs-1)*m_distance; 00094 00095 /* sample from std Gaussian */ 00096 float64_t x=CMath::randn_double(); 00097 float64_t y=CMath::randn_double(); 00098 00099 /* transform through cholesky and add offset */ 00100 result[0]=m_cholesky(0, 0)*x+m_cholesky(0, 1)*y+x_offset; 00101 result[1]=m_cholesky(1, 0)*x+m_cholesky(1, 1)*y+y_offset; 00102 00103 /* save example back to superclass */ 00104 CGaussianBlobsDataGenerator::current_vector=result; 00105 00106 SG_SDEBUG("leaving CGaussianBlobsDataGenerator::get_next_example()\n"); 00107 return true; 00108 } 00109 00110 void CGaussianBlobsDataGenerator::release_example() 00111 { 00112 SGVector<float64_t> temp=SGVector<float64_t>(); 00113 CGaussianBlobsDataGenerator::current_vector=temp; 00114 } 00115