int_array Utils::Sort(int_array &array_Renamed) { int_array index = initialIndex((int)array_Renamed.size()); int_array newIndex(array_Renamed.size()); int_array helpIndex; int numEqual; quickSort(array_Renamed, index, 0, (int)array_Renamed.size() - 1); // Make sort stable int i = 0; while (i < index.size()) { numEqual = 1; for (int j = i + 1; ((j < index.size()) && (array_Renamed[index[i]] == array_Renamed[index[j]])); j++) { numEqual++; } if (numEqual > 1) { helpIndex = int_array(numEqual); for (int j = 0; j < numEqual; j++) { helpIndex[j] = i + j; } quickSort(index, helpIndex, 0, numEqual - 1); for (int j = 0; j < numEqual; j++) { newIndex[i + j] = index[helpIndex[j]]; } i += numEqual; } else { newIndex[i] = index[i]; i++; } } return newIndex; }
/** factrs For symmetric structure, transforms submatricies to form matricies of the symmetric modes and calls routine to LU decompose matricies. If no symmetry [nrow = np], the routine is called to LU decompose the complete matrix. */ void factrs(nec_output_file& s_output, int64_t np, int64_t nrow, complex_array& a, int_array& ip ) { DEBUG_TRACE("factrs(" << np << "," << nrow << ")"); if (nrow == np) { // no symmetry lu_decompose(s_output, np, a, ip, nrow ); return; } int num_symmetric_modes = nrow / np; DEBUG_TRACE("\tnum_symmetric_modes = " << num_symmetric_modes); for (int mode = 0; mode < num_symmetric_modes; mode++ ) { int64_t mode_offset = mode * np; complex_array a_temp = a.segment(mode_offset, a.size()-mode_offset); int_array ip_temp = ip.segment(mode_offset, ip.size()-mode_offset); lu_decompose(s_output, np, a_temp, ip_temp, nrow ); } }
int Utils::minIndex(int_array &ints) { int minimum = 0; int minIndex = 0; for (int i = 0; i < ints.size(); i++) { if ((i == 0) || (ints[i] < minimum)) { minIndex = i; minimum = ints[i]; } } return minIndex; }
int Utils::maxIndex(int_array &ints) { int maximum = 0; int maxIndex = 0; for (int i = 0; i < ints.size(); i++) { if ((i == 0) || (ints[i] > maximum)) { maxIndex = i; maximum = ints[i]; } } return maxIndex; }
/*! \brief Solve system of linear equations Subroutine to solve the matrix equation lu*x=b where l is a unit lower triangular matrix and u is an upper triangular matrix both of which are stored in a. the rhs vector b is input and the solution is returned through vector b. (matrix transposed) */ void solve_lapack( int n, complex_array& a, int_array& ip, complex_array& b, int64_t ndim ) { DEBUG_TRACE("solve_lapack(" << n << "," << ndim << ")"); int info = clapack_zgetrs (CblasColMajor, CblasNoTrans, n, 1, (void*) a.data(), ndim, ip.data(), b.data(), n); if (0 != info) { /* The factorization has been completed, but the factor U is exactly singular, and division by zero will occur if it is used to solve a system of equations. */ throw new nec_exception("nec++: Solving Failed: ",info); } }
int ThresholdCurve::binarySearch(const int_array &index, const double_array &vals, const double target) { int lo = 0, hi = (int)index.size() - 1; while (hi - lo > 1) { int mid = lo + (hi - lo) / 2; double midval = vals[index[mid]]; if (target > midval) { lo = mid; } else if (target < midval) { hi = mid; } else { while ((mid > 0) && (vals[index[mid - 1]] == target)) { mid--; } return mid; } } return lo; }
int Utils::kthSmallestValue(int_array &array_Renamed, int k) { int_array index = initialIndex((int)array_Renamed.size()); return array_Renamed[index[select(array_Renamed, index, 0, (int)array_Renamed.size() - 1, k)]]; }
int >; TEST_CASE( "container::dynamic_array", "[container]" ) { typedef fcppt::container::dynamic_array< int > int_array; int_array array1{ 10 }; CHECK( std::distance( array1.data(), array1.data_end() ) == 10 ); CHECK( array1.size() == 10u
/** Subroutine solves, for symmetric structures, handles the transformation of the right hand side vector and solution of the matrix eq. \param neq number of equations? \param nrh dimension of right hand vector? */ void solves(complex_array& a, int_array& ip, complex_array& b, int64_t neq, int64_t nrh, int64_t np, int64_t n, int64_t mp, int64_t m, int64_t nop, complex_array& symmetry_array) { DEBUG_TRACE("solves(" << neq << "," << nrh << "," << np << "," << n << ")"); DEBUG_TRACE(" ( nop=" << nop << ")"); /* Allocate some scratch memory */ complex_array scm; scm.resize(n + 2*m); int npeq= np+ 2*mp; nec_float fnop = nop; nec_float fnorm = 1.0/ fnop; int nrow= neq; if ( nop != 1) { for (int ic = 0; ic < nrh; ic++ ) { int64_t column_offset = ic*neq; if ( (n != 0) && (m != 0) ) { for (int i = 0; i < neq; i++ ) scm[i]= b[i+column_offset]; int j= np-1; for (int k = 0; k < nop; k++ ) { if ( k != 0 ) { int ia= np-1; for (int i = 0; i < np; i++ ) { ia++; j++; b[j+column_offset]= scm[ia]; } if ( k == (nop-1) ) continue; } /* if ( k != 0 ) */ int mp2 = 2*mp; int ib= n-1; for (int i = 0; i < mp2; i++ ) { ib++; j++; b[j+column_offset]= scm[ib]; } } /* for( k = 0; k < nop; k++ ) */ } /* if ( (n != 0) && (m != 0) ) */ /* transform matrix eq. rhs vector according to symmetry modes */ for (int i = 0; i < npeq; i++ ) { for (int k = 0; k < nop; k++ ) { int64_t ia= i+ k* npeq; scm[k]= b[ia+column_offset]; } nec_complex sum_normal(scm[0]); for (int k = 1; k < nop; k++ ) sum_normal += scm[k]; b[i+column_offset]= sum_normal * fnorm; for (int k = 1; k < nop; k++ ) { int ia= i+ k* npeq; nec_complex sum(scm[0]); for (int j = 1; j < nop; j++ ) sum += scm[j]* conj( symmetry_array[k+j*nop]); b[ia+column_offset]= sum* fnorm; } } /* for( i = 0; i < npeq; i++ ) */ } /* for( ic = 0; ic < nrh; ic++ ) */ } /* if ( nop != 1) */ /* solve each mode equation */ for (int kk = 0; kk < nop; kk++ ) { int ia= kk* npeq; for (int ic = 0; ic < nrh; ic++ ) { int column_offset = ic*neq; complex_array a_sub = a.segment(ia, a.size()-ia); complex_array b_sub = b.segment(ia+column_offset, b.size() - (ia+column_offset) ); int_array ip_sub = ip.segment(ia, ip.size()-ia); solve( npeq, a_sub, ip_sub, b_sub, nrow ); } } /* for( kk = 0; kk < nop; kk++ ) */ if ( nop == 1) { return; } /* inverse transform the mode solutions */ for (int ic = 0; ic < nrh; ic++ ) { int column_offset = ic*neq; for (int i = 0; i < npeq; i++ ) { for (int k = 0; k < nop; k++ ) { int ia= i+ k* npeq; scm[k]= b[ia+column_offset]; } nec_complex sum_normal(scm[0]); for (int k = 1; k < nop; k++ ) sum_normal += scm[k]; b[i+column_offset]= sum_normal; for (int k = 1; k < nop; k++ ) { int ia= i+ k* npeq; nec_complex sum(scm[0]); for (int j = 1; j < nop; j++ ) sum += scm[j]* symmetry_array[k+j*nop]; b[ia+column_offset]= sum; } } /* for( i = 0; i < npeq; i++ ) */ if ( (n == 0) || (m == 0) ) continue; for (int i = 0; i < neq; i++ ) scm[i]= b[i+column_offset]; int j = np-1; for (int32_t k = 0; k < nop; k++ ) { if ( k != 0 ) { int ia = np-1; for (int32_t i = 0; i < np; i++ ) { ia++; j++; b[ia+column_offset]= scm[j]; } if ( k == nop) continue; } /* if ( k != 0 ) */ int ib = n-1; int mp2 = 2* mp; for (int i = 0; i < mp2; i++ ) { ib++; j++; b[ib+column_offset]= scm[j]; } } /* for( k = 0; k < nop; k++ ) */ } /* for( ic = 0; ic < nrh; ic++ ) */ }
/*! \brief Use lapack to perform LU decomposition */ void lu_decompose_lapack(nec_output_file& s_output, int64_t n, complex_array& a_in, int_array& ip, int64_t ndim) { UNUSED(s_output); DEBUG_TRACE("lu_decompose_lapack(" << n << "," << ndim << ")"); ASSERT(n <= ndim); #ifdef NEC_MATRIX_CHECK cout << "atlas_a = "; to_octave(a_in,n,ndim); #endif /* Un-transpose the matrix for Gauss elimination */ for (int i = 1; i < n; i++ ) { int i_offset = i * ndim; int j_offset = 0; for (int j = 0; j < i; j++ ) { nec_complex aij = a_in[i+j_offset]; a_in[i+j_offset] = a_in[j+i_offset]; a_in[j+i_offset] = aij; j_offset += ndim; } } /* Now call the LAPACK LU-Decomposition ZGETRF computes an LU factorization of a general M-by-N matrix A * using partial pivoting with row interchanges. * * The factorization has the form * A = P * L * U * where P is a permutation matrix, L is lower triangular with unit * diagonal elements (lower trapezoidal if m > n), and U is upper * triangular (upper trapezoidal if m < n). Arguments * ========= * * M (input) INTEGER * The number of rows of the matrix A. M >= 0. * * N (input) INTEGER * The number of columns of the matrix A. N >= 0. * * A (input/output) COMPLEX*16 array, dimension (LDA,N) * On entry, the M-by-N matrix to be factored. * On exit, the factors L and U from the factorization * A = P*L*U; the unit diagonal elements of L are not stored. * * LDA (input) INTEGER * The leading dimension of the array A. LDA >= max(1,M). * * IPIV (output) INTEGER array, dimension (min(M,N)) * The pivot indices; for 1 <= i <= min(M,N), row i of the * matrix was interchanged with row IPIV(i). * * INFO (output) INTEGER * = 0: successful exit * < 0: if INFO = -i, the i-th argument had an illegal value * > 0: if INFO = i, U(i,i) is exactly zero. The factorization * has been completed, but the factor U is exactly * singular, and division by zero will occur if it is used * to solve a system of equations. */ int info = clapack_zgetrf (CblasColMajor, n, n, (void*) a_in.data(), ndim, ip.data()); if (0 != info) { /* The factorization has been completed, but the factor U is exactly singular, and division by zero will occur if it is used to solve a system of equations. */ throw new nec_exception("nec++: LU Decomposition Failed: ",info); } #ifdef NEC_MATRIX_CHECK cout << "atlas_solved = "; to_octave(a_in,n,ndim); cout << "atlas_ip = "; to_octave(ip,n); #endif }
void to_octave(int_array& a, int n) { to_octave(a.data(),n); }
void to_octave(int_array& a, int n) { to_octave(a.get_ptr(),n); }