21 #ifndef bempp_modified_aca_hpp
22 #define bempp_modified_aca_hpp
24 #include "../common/common.hpp"
25 #include "bempp/common/config_ahmed.hpp"
29 #ifdef __INTEL_COMPILER
30 #pragma warning(disable:381)
35 #ifdef __INTEL_COMPILER
36 #pragma warning(default:381)
39 #include <boost/scoped_array.hpp>
47 template <
class abs_T>
48 bool select_pivot_with_min_norm2(
unsigned n,
const abs_T* norm2,
49 const int* apprx_times ,
53 abs_T min_norm2 = std::numeric_limits<abs_T>::max();
54 for (
unsigned i = 0; i < n; ++i)
55 if (apprx_times[i] >= 0 && norm2[i] < min_norm2) {
62 template<
class T,
class MATGEN_T>
63 bool ACAs(MATGEN_T& MatGen,
unsigned b1,
unsigned n1,
unsigned b2,
unsigned n2,
64 double eps,
unsigned kmax,
unsigned i0,
unsigned& k, T* &U, T* &V,
65 const cluster* c1,
const cluster* c2)
67 typedef typename num_traits<T>::abs_type abs_T;
70 const unsigned maxit = std::min(n1, n2);
72 abs_T scale = MatGen.scale(b1, n1, b2, n2, c1, c2);
74 U =
new T[(kmax+1)*n1];
75 V =
new T[(kmax+1)*n2];
76 assert(U != NULL && V != NULL);
79 boost::scoped_array<int> Z(
new int[n1]), S(
new int[n2]);
80 for (
unsigned l=0; l<n1; ++l)
82 for (
unsigned l=0; l<n2; ++l)
85 boost::scoped_array<T> orig_row(
new T[n2]);
86 boost::scoped_array<T> orig_col(
new T[n1]);
88 boost::scoped_array<abs_T> orig_row_norm2(
new abs_T[n2]);
89 boost::scoped_array<abs_T> orig_col_norm2(
new abs_T[n1]);
93 const unsigned ROW = 0, COL = 1;
94 const unsigned NORMAL = 0, FIRST_SHOT = 1, SECOND_SHOT = 2;
96 unsigned stage = NORMAL;
99 unsigned next_pivot = i0;
114 bool retry_if_zero = (stage == NORMAL);
117 status = ACA_row_step(
118 MatGen, b1, n1, b2, n2, klast, next_pivot, k, no,
119 Z.get(), S.get(), U, V, nrmlsk2, scale, c1, c2,
120 retry_if_zero, orig_row.get(), orig_col.get());
122 status = ACA_col_step(
123 MatGen, b1, n1, b2, n2, next_pivot, k, no,
124 Z.get(), S.get(), U, V, nrmlsk2, scale, c1, c2,
125 retry_if_zero, orig_row.get(), orig_col.get());
128 bool stpcrit =
false;
129 if (status == ACA_STATUS_SUCCESS) {
132 for (
unsigned l=0; l<k; ++l)
133 sum += blas::scpr(n1, U+l*n1, U+k*n1) * blas::scpr(n2, V+k*n2, V+l*n2);
134 nrms2 += 2. * Re(sum) + nrmlsk2;
136 stpcrit = (nrmlsk2 < eps * eps * nrms2);
138 scale = sqrt(nrmlsk2/(n1*n2));
143 }
else if (status == ACA_STATUS_EARLY_EXIT)
147 assert(status == ACA_STATUS_REMAINDER_IS_ZERO);
152 if (stage == SECOND_SHOT)
154 else if (stage == FIRST_SHOT) {
157 bool found = select_pivot_with_min_norm2(
158 n2, orig_row_norm2.get(), S.get(), next_pivot);
164 bool found = select_pivot_with_min_norm2(
165 n1, orig_col_norm2.get(), Z.get(), next_pivot);
172 assert(stage == NORMAL);
173 for (
unsigned i = 0; i < n2; ++i)
174 orig_row_norm2[i] = abs2(orig_row[i]);
175 for (
unsigned i = 0; i < n1; ++i)
176 orig_col_norm2[i] = abs2(orig_col[i]);
179 bool found = select_pivot_with_min_norm2(
180 n1, orig_col_norm2.get(), Z.get(), next_pivot);
186 bool found = select_pivot_with_min_norm2(
187 n2, orig_row_norm2.get(), S.get(), next_pivot);
199 }
while (no < maxit && k < kmax);
205 template<
class T,
class T1,
class T2,
class MATGEN_T>
206 void apprx_unsym_shooting(
207 MATGEN_T& MatGen, mblock<T>* &mbl, bbxbemblcluster<T1,T2>* bl,
208 double eps,
unsigned rankmax)
210 apprx_unsym_generic(&ACAs<T, MATGEN_T>, MatGen, mbl, bl, eps, rankmax);