ViennaCL - The Vienna Computing Library
1.5.1
|
00001 #ifndef VIENNACL_LINALG_BISECT_HPP_ 00002 #define VIENNACL_LINALG_BISECT_HPP_ 00003 00004 /* ========================================================================= 00005 Copyright (c) 2010-2014, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 Portions of this software are copyright by UChicago Argonne, LLC. 00009 00010 ----------------- 00011 ViennaCL - The Vienna Computing Library 00012 ----------------- 00013 00014 Project Head: Karl Rupp rupp@iue.tuwien.ac.at 00015 00016 (A list of authors and contributors can be found in the PDF manual) 00017 00018 License: MIT (X11), see file LICENSE in the base directory 00019 ============================================================================= */ 00020 00027 #include <vector> 00028 #include <cmath> 00029 #include <limits> 00030 #include <cstddef> 00031 #include "viennacl/meta/result_of.hpp" 00032 00033 namespace viennacl 00034 { 00035 namespace linalg 00036 { 00037 00038 namespace detail 00039 { 00043 template <typename T, typename OtherVectorType> 00044 void copy_vec_to_vec(viennacl::vector<T> const & src, OtherVectorType & dest) 00045 { 00046 viennacl::copy(src, dest); 00047 } 00048 00049 template <typename OtherVectorType, typename T> 00050 void copy_vec_to_vec(OtherVectorType const & src, viennacl::vector<T> & dest) 00051 { 00052 viennacl::copy(src, dest); 00053 } 00054 00055 template <typename VectorType1, typename VectorType2> 00056 void copy_vec_to_vec(VectorType1 const & src, VectorType2 & dest) 00057 { 00058 for (vcl_size_t i=0; i<src.size(); ++i) 00059 dest[i] = src[i]; 00060 } 00061 } 00062 00070 template< typename VectorT > 00071 std::vector< 00072 typename viennacl::result_of::cpu_value_type<typename VectorT::value_type>::type 00073 > 00074 bisect(VectorT const & alphas, VectorT const & betas) 00075 { 00076 typedef typename viennacl::result_of::value_type<VectorT>::type ScalarType; 00077 typedef typename viennacl::result_of::cpu_value_type<ScalarType>::type CPU_ScalarType; 00078 00079 vcl_size_t size = betas.size(); 00080 std::vector<CPU_ScalarType> x_temp(size); 00081 00082 00083 std::vector<CPU_ScalarType> beta_bisect; 00084 std::vector<CPU_ScalarType> wu; 00085 00086 double rel_error = std::numeric_limits<CPU_ScalarType>::epsilon(); 00087 beta_bisect.push_back(0); 00088 00089 for(vcl_size_t i = 1; i < size; i++){ 00090 beta_bisect.push_back(betas[i] * betas[i]); 00091 } 00092 00093 double xmin = alphas[size - 1] - std::fabs(betas[size - 1]); 00094 double xmax = alphas[size - 1] + std::fabs(betas[size - 1]); 00095 00096 for(vcl_size_t i = 0; i < size - 1; i++) 00097 { 00098 double h = std::fabs(betas[i]) + std::fabs(betas[i + 1]); 00099 if (alphas[i] + h > xmax) 00100 xmax = alphas[i] + h; 00101 if (alphas[i] - h < xmin) 00102 xmin = alphas[i] - h; 00103 } 00104 00105 00106 double eps1 = 1e-6; 00107 /*double eps2 = (xmin + xmax > 0) ? (rel_error * xmax) : (-rel_error * xmin); 00108 if(eps1 <= 0) 00109 eps1 = eps2; 00110 else 00111 eps2 = 0.5 * eps1 + 7.0 * eps2; */ 00112 00113 double x0 = xmax; 00114 00115 for(vcl_size_t i = 0; i < size; i++) 00116 { 00117 x_temp[i] = xmax; 00118 wu.push_back(xmin); 00119 } 00120 00121 for(long k = static_cast<long>(size) - 1; k >= 0; --k) 00122 { 00123 double xu = xmin; 00124 for(long i = k; i >= 0; --i) 00125 { 00126 if(xu < wu[k-i]) 00127 { 00128 xu = wu[i]; 00129 break; 00130 } 00131 } 00132 00133 if(x0 > x_temp[k]) 00134 x0 = x_temp[k]; 00135 00136 double x1 = (xu + x0) / 2.0; 00137 while (x0 - xu > 2.0 * rel_error * (std::fabs(xu) + std::fabs(x0)) + eps1) 00138 { 00139 vcl_size_t a = 0; 00140 double q = 1; 00141 for(vcl_size_t i = 0; i < size; i++) 00142 { 00143 if(q != 0) 00144 q = alphas[i] - x1 - beta_bisect[i] / q; 00145 else 00146 q = alphas[i] - x1 - std::fabs(betas[i] / rel_error); 00147 00148 if(q < 0) 00149 a++; 00150 } 00151 00152 if (a <= static_cast<vcl_size_t>(k)) 00153 { 00154 xu = x1; 00155 if(a < 1) 00156 wu[0] = x1; 00157 else 00158 { 00159 wu[a] = x1; 00160 if(x_temp[a - 1] > x1) 00161 x_temp[a - 1] = x1; 00162 } 00163 } 00164 else 00165 x0 = x1; 00166 00167 x1 = (xu + x0) / 2.0; 00168 } 00169 x_temp[k] = x1; 00170 } 00171 return x_temp; 00172 } 00173 00174 } // end namespace linalg 00175 } // end namespace viennacl 00176 #endif