imate
C++/CUDA Reference
Loading...
Searching...
No Matches
ConvergenceTools< DataType > Class Template Reference

A static class to compute the trace of implicit matrix functions using stochastic Lanczos quadrature method. This class acts as a templated namespace, where the member methods is public and static. The internal private member functions are also static. More...

#include <convergence_tools.h>

Static Public Member Functions

static FlagType check_convergence (DataType **samples, const IndexType min_num_samples, const IndexType num_inquiries, const IndexType *processed_samples_indices, const IndexType num_processed_samples, const DataType confidence_level, const DataType error_atol, const DataType error_rtol, DataType *error, IndexType *num_samples_used, FlagType *converged)
 Checks if the standard deviation of the set of the cumulative averages of trace estimators converged below the given tolerance.
 
static void average_estimates (const DataType confidence_level, const DataType outlier_significance_level, const IndexType num_inquiries, const IndexType max_num_samples, const IndexType *num_samples_used, const IndexType *processed_samples_indices, DataType **samples, IndexType *num_outliers, DataType *trace, DataType *error)
 Averages the estimates of trace. Removes outliers and reevaluates the error to take into account for the removal of the outliers.
 

Detailed Description

template<typename DataType>
class ConvergenceTools< DataType >

A static class to compute the trace of implicit matrix functions using stochastic Lanczos quadrature method. This class acts as a templated namespace, where the member methods is public and static. The internal private member functions are also static.

See also
Diagonalization

Definition at line 36 of file convergence_tools.h.

Member Function Documentation

◆ average_estimates()

template<typename DataType >
void ConvergenceTools< DataType >::average_estimates ( const DataType  confidence_level,
const DataType  outlier_significance_level,
const IndexType  num_inquiries,
const IndexType  max_num_samples,
const IndexType num_samples_used,
const IndexType processed_samples_indices,
DataType **  samples,
IndexType num_outliers,
DataType *  trace,
DataType *  error 
)
static

Averages the estimates of trace. Removes outliers and reevaluates the error to take into account for the removal of the outliers.

Note
The elimination of outliers does not affect the elements of samples array, rather it only affects the re-evaluation of trace and error arrays.
Parameters
[in]confidence_levelThe confidence level of the error, which is a number between 0 and 1. This affects the scale of error.
[in]outlier_significance_levelOne minus the confidence level of the uncertainty band of the outlier. This is a number between 0 and 1. Confidence level of outleir and significance level of outlier are commlement of each other.
[in]num_inquiriesThe number of batches of parameters. This function computes num_inquiries values of trace corresponding to different batch of parameters of the linear operator A. Hence, the number of output trace is num_inquiries. Hence, it is the number of columns of the output array samples.
[in]max_num_samplesThe number of times that the trace estimation is repeated. The output trace value is the average of the samples. Hence, this is the number of rows of the output array samples. Larger number of samples leads to a better trace estimation. The computational const linearly increases with number of samples.
[in]num_samples_used1D array of the size of the number of columns of samples. Each element indicates how many iterations were used till convergence is reached for each column of the samples. The number of iterations should be a number between min_num_samples and max_num_samples.
[in]processed_samples_indicesA 1D array indicating the processing order of rows of the samples. In paralleli processing, this order of processing the rows of samples is not necessarly sequential.
[out]samples2D array of all estimated trace samples. The shape of this array is (max_num_samples*num_inquiries). The average of the rows is also given in trace array.
[out]num_outliers1D array with the size of number of columns of samples. Each element indicates how many rows of the samples array were outliers and were removed during averaging rows of samples.
[out]traceThe output trace of size num_inquiries. These values are the average of the rows of samples array.
[out]errorThe error of estimation of trace, which is the standard deviation of the rows of samples array. The size of this array is num_inquiries.

Definition at line 289 of file convergence_tools.cpp.

300{
301 IndexType i;
302 IndexType j;
303 DataType summand;
304 DataType mean;
305 DataType mean_abs;
306 DataType std;
307 DataType mean_discrepancy;
308 DataType outlier_half_interval;
309
310 // Flag which samples are outliers
311 FlagType* outlier_indices = new FlagType[max_num_samples];
312
313 // Quantile of normal distribution (usually known as the "z" coefficient)
314 DataType error_z_score = std::sqrt(2) * erf_inv(confidence_level);
315
316 // Confidence level of outlier is the complement of significance level
317 DataType outlier_confidence_level = 1.0 - outlier_significance_level;
318
319 // Quantile of normal distribution area where is not considered as outlier
320 DataType outlier_z_score = std::sqrt(2.0) * \
321 erf_inv(outlier_confidence_level);
322
323 for (j=0; j < num_inquiries; ++j)
324 {
325 // Initialize outlier indices for each column of samples
326 for (i=0; i < max_num_samples; ++i)
327 {
328 outlier_indices[i] = 0;
329 }
330 num_outliers[j] = 0;
331
332 // Compute mean of the j-th column
333 summand = 0.0;
334 for (i=0; i < num_samples_used[j]; ++i)
335 {
336 summand += samples[processed_samples_indices[i]][j];
337 }
338 mean = summand / num_samples_used[j];
339
340 // Compute mean of the absolute values of j-th column
341 summand = 0.0;
342 for (i=0; i < num_samples_used[j]; ++i)
343 {
344 summand += std::abs(samples[processed_samples_indices[i]][j]);
345 }
346 mean_abs = summand / num_samples_used[j];
347
348 // If mean of absolute values is zero, do not scale data with it as it
349 // causes divide by zero. In this case, all sample data are zero, and
350 // there is no need to scale them.
351 DataType zero = 0.0;
352 if (c_arithmetics::is_equal(mean_abs, zero))
353 {
354 mean_abs = 1.0;
355 }
356
357 // Compute std of the j-th column
358 if (num_samples_used[j] > 1)
359 {
360 summand = 0.0;
361 for (i=0; i < num_samples_used[j]; ++i)
362 {
363 mean_discrepancy = \
364 samples[processed_samples_indices[i]][j] - mean;
365
366 // Normalize to the mean of absolute values to avoid underflow
367 // and overflow, but later, re-scale it back. The underflow or
368 // overflow is caused by taking the square two lines below.
369 mean_discrepancy /= mean_abs;
370
371 summand += mean_discrepancy * mean_discrepancy;
372 }
373 std = std::sqrt(summand / (num_samples_used[j] - 1.0));
374
375 // Re-scale back by mean of absolute values
376 std *= mean_abs;
377 }
378 else
379 {
380 std = INFINITY;
381 }
382
383 // Outlier half interval
384 outlier_half_interval = outlier_z_score * std;
385
386 // Find outliers by the difference of each element from mean
387 for (i=0; i < num_samples_used[j]; ++i)
388 {
389 mean_discrepancy = samples[processed_samples_indices[i]][j] - mean;
390 if (std::abs(mean_discrepancy) > outlier_half_interval)
391 {
392 // Outlier detected
393 outlier_indices[i] = 1;
394 num_outliers[j] += 1;
395 }
396 }
397
398 // Re-evaluate mean but leave out outliers
399 summand = 0.0;
400 for (i=0; i < num_samples_used[j]; ++i)
401 {
402 if (outlier_indices[i] == 0)
403 {
404 summand += samples[processed_samples_indices[i]][j];
405 }
406 }
407 mean = summand / (num_samples_used[j] - num_outliers[j]);
408
409 // Re-evaluate std but leave out outliers
410 if (num_samples_used[j] > 1 + num_outliers[j])
411 {
412 summand = 0.0;
413 for (i=0; i < num_samples_used[j]; ++i)
414 {
415 if (outlier_indices[i] == 0)
416 {
417 mean_discrepancy = \
418 samples[processed_samples_indices[i]][j] - mean;
419
420 // Normalize to the mean of absolute values to avoid underflow
421 // and overflow, but later, re-scale it back. The underflow or
422 // overflow is caused by taking the square two lines below.
423 mean_discrepancy /= mean_abs;
424
425 summand += mean_discrepancy * mean_discrepancy;
426 }
427 }
428 std = std::sqrt(
429 summand/(num_samples_used[j] - num_outliers[j] - 1.0));
430
431 // Re-scale back by mean of absolute values
432 std *= mean_abs;
433 }
434 else
435 {
436 std = INFINITY;
437 }
438
439 // trace and its error
440 trace[j] = mean;
441 error[j] = error_z_score * std / \
442 std::sqrt(num_samples_used[j] - num_outliers[j]);
443 }
444
445 delete[] outlier_indices;
446}
bool is_equal(DataType x, DataType y)
Check if two floating point numbers are equal within a tolerance.
Definition _c_is_equal.h:49
double erf_inv(const double x)
Inverse error function.
int FlagType
Definition types.h:68
int IndexType
Definition types.h:65

References erf_inv(), and c_arithmetics::is_equal().

Referenced by cTraceEstimator< DataType >::c_trace_estimator(), and cuTraceEstimator< DataType >::cu_trace_estimator().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_convergence()

template<typename DataType >
FlagType ConvergenceTools< DataType >::check_convergence ( DataType **  samples,
const IndexType  min_num_samples,
const IndexType  num_inquiries,
const IndexType processed_samples_indices,
const IndexType  num_processed_samples,
const DataType  confidence_level,
const DataType  error_atol,
const DataType  error_rtol,
DataType *  error,
IndexType num_samples_used,
FlagType converged 
)
static

Checks if the standard deviation of the set of the cumulative averages of trace estimators converged below the given tolerance.

The convergence criterion for each trace inquiry is if:

            standard_deviation < max(rtol * average[i], atol)

        where \c rtol and \c atol are relative and absolute tolerances,
        respectively. If this criterion is satisfied for *all* trace
        inquiries, this function returns \c 1, otherwise \c 0.
Parameters
[in]samplesA 2D array of the estimated trace. This array has the shape (max_num_samples,num_inquiries). Each column of this array is the estimated trace values for a different trace inquiry. The rows are Monte-Carlo samples of the estimation of trace. The cumulative average of the rows are expected to converge. Note that because of parallel processing, the rows of this array are not filled sequentially. The list of filled rows are stored in processed_samples_indices.
[in]min_num_samplesMinimum number of sample iterations.
[in]num_inquiriesNumber of columns of samples array.
[in]processed_samples_indicesA 1D array indicating the processing order of rows of the samples. In parallel processing, this order of processing the rows of samples is not necessarly sequential.
[in]num_processed_samplesA counter that keeps track of how many samples were processed so far in the iterations.
[in]confidence_levelThe confidence level of the error, which is a number between 0 and 1. This affects the scale of error.
[in]error_atolAbsolute tolerance criterion to be compared with the standard deviation of the cumulative averages. If error_atol is zero, it is ignored, and only rtol is used.
[in]error_rtolRelative tolerance criterion to be compared with the standard deviation of the cumulative averages. If error_rtol is zero, it is ignored, and only error_atol is used.
[out]errorThe error of estimation of trace, which is the standard deviation of the rows of samples array. The size of this array is num_inquiries.
[out]num_samples_used1D array of the size of the number of columns of samples. Each element indicates how many iterations were used till convergence is reached for each column of the samples. The number of iterations should be a number between min_num_samples and max_num_samples.
[out]converged1D array of the size of the number of columns of samples. Each element indicates which column of samples has converged to the tolerance criteria. Normally, if the num_samples_used is less than max_num_samples, it indicates that the convergence has reached. the rows of samples array. The size of this array is num_inquiries.
Returns
A signal to indicate the status of computation:
  • 1 indicates successful convergence within the given tolerances was met. Convergence is achieved when all elements of convergence array are below convergence_atol or convergence_rtol times trace.
  • 0 indicates the convergence criterion was not met for at least one of the trace inquiries.

Definition at line 96 of file convergence_tools.cpp.

108{
109 FlagType all_converged;
110 IndexType j;
111
112 // If number of processed samples are not enough, set to not converged yet.
113 // This is essential since in the first few iterations, the standard
114 // deviation of the cumulative averages are still too small.
115 if (num_processed_samples < min_num_samples)
116 {
117 // Skip computing error. Fill outputs with trivial initial values
118 for (j=0; j < num_inquiries; j++)
119 {
120 error[j] = INFINITY;
121 converged[j] = 0;
122 num_samples_used[j] = num_processed_samples;
123 }
124 all_converged = 0;
125 return all_converged;
126 }
127
128 IndexType i;
129 DataType summand;
130 DataType mean;
131 DataType mean_abs;
132 DataType std;
133 DataType mean_discrepancy;
134 DataType data;
135
136 // Quantile of normal distribution (usually known as the "z" coefficient)
137 DataType standard_z_score = std::sqrt(2) * \
138 static_cast<DataType>(erf_inv(static_cast<double>(confidence_level)));
139
140 // For each column of samples, compute error of all processed rows
141 for (j=0; j < num_inquiries; ++j)
142 {
143 // Do not check convergence if j-th column already converged
144 if (converged[j] == 0)
145 {
146 // mean of j-th column using all processed rows of j-th column
147 summand = 0.0;
148 for (i=0; i < num_processed_samples; ++i)
149 {
150 summand += samples[processed_samples_indices[i]][j];
151 }
152 mean = summand / num_processed_samples;
153
154 // mean of absolute values of j-th column using all processed rows
155 // of j-th column
156 summand = 0.0;
157 for (i=0; i < num_processed_samples; ++i)
158 {
159 summand += std::abs(samples[processed_samples_indices[i]][j]);
160 }
161 mean_abs = summand / num_processed_samples;
162
163 // If mean of absolute values is zero, do not scale data with it as
164 // it causes divide by zero. In this case, all sample data are
165 // zero, and there is no need to scale them.
166 DataType zero = 0.0;
167 if (c_arithmetics::is_equal(mean_abs, zero))
168 {
169 mean_abs = 1.0;
170 }
171
172 // std of j-th column using all processed rows of j-th column
173 if (num_processed_samples > 1)
174 {
175 summand = 0.0;
176 for (i=0; i < num_processed_samples; ++i)
177 {
178 data = samples[processed_samples_indices[i]][j];
179 mean_discrepancy = data - mean;
180
181 // Normalize to the mean of absolute values to avoid
182 // underflow and overflow, but later, re-scale it back. The
183 // underflow or overflow is caused by taking the square two
184 // lines below.
185 mean_discrepancy /= mean_abs;
186
187 summand += mean_discrepancy * mean_discrepancy;
188 }
189 std = std::sqrt(summand / (num_processed_samples - 1.0));
190
191 // Re-scale back by mean of absolute values
192 std *= mean_abs;
193 }
194 else
195 {
196 std = INFINITY;
197 }
198
199 // Compute error based of std and confidence level
200 error[j] = standard_z_score * std / \
201 std::sqrt(num_processed_samples);
202
203 // Check error with atol and rtol to find if j-th column converged
204 if (error[j] < std::max(error_atol, error_rtol*mean))
205 {
206 converged[j] = 1;
207 }
208
209 // Update how many samples used so far to average j-th column
210 num_samples_used[j] = num_processed_samples;
211 }
212 }
213
214 // Check convergence is reached for all columns (all inquiries)
215 all_converged = 1;
216 for (j=0; j < num_inquiries; ++j)
217 {
218 if (converged[j] == 0)
219 {
220 // The j-th column not converged.
221 all_converged = 0;
222 break;
223 }
224 }
225
226 return all_converged;
227}

References erf_inv(), and c_arithmetics::is_equal().

Referenced by cTraceEstimator< DataType >::c_trace_estimator(), and cuTraceEstimator< DataType >::cu_trace_estimator().

Here is the call graph for this function:
Here is the caller graph for this function:

The documentation for this class was generated from the following files: