94 Eigen::MatrixXd matPnt,
95 Eigen::MatrixXd matOri)
99 Eigen::MatrixXd r, r2, r5, x, y, z, mx, my, mz, Tx, Ty, Tz, lf;
101 iNchan = matPnt.rows();
104 matPnt.array().col(0) -= matPos(0);
105 matPnt.array().col(1) -= matPos(1);
106 matPnt.array().col(2) -= matPos(2);
108 r = matPnt.array().square().rowwise().sum().sqrt();
110 r2 = r5 = x = y = z = mx = my = mz = Tx = Ty = Tz = lf = Eigen::MatrixXd::Zero(iNchan, 3);
112 for (
int i = 0; i < iNchan; i++) {
113 r2.row(i).array().fill(pow(r(i), 2));
114 r5.row(i).array().fill(pow(r(i), 5));
117 for (
int i = 0; i < iNchan; i++) {
118 x.row(i).array().fill(matPnt(i, 0));
119 y.row(i).array().fill(matPnt(i, 1));
120 z.row(i).array().fill(matPnt(i, 2));
123 mx.col(0).array().fill(1);
124 my.col(1).array().fill(1);
125 mz.col(2).array().fill(1);
127 Tx = 3 * x.cwiseProduct(matPnt) - mx.cwiseProduct(r2);
128 Ty = 3 * y.cwiseProduct(matPnt) - my.cwiseProduct(r2);
129 Tz = 3 * z.cwiseProduct(matPnt) - mz.cwiseProduct(r2);
131 for (
int i = 0; i < iNchan; i++) {
132 lf(i, 0) = Tx.row(i).dot(matOri.row(i));
133 lf(i, 1) = Ty.row(i).dot(matOri.row(i));
134 lf(i, 2) = Tz.row(i).dot(matOri.row(i));
137 for (
int i = 0; i < iNchan; i++) {
138 for (
int j = 0; j < 3; j++) {
139 lf(i, j) = u0 * lf(i, j) / (4 *
M_PI * r5(i, j));
206 [[maybe_unused]]
int iDisplay,
207 const Eigen::MatrixXd& matData,
208 const Eigen::MatrixXd& matProjectors,
212 double tolx, tolf, rho, chi, psi, sigma, func_evals, usual_delta, zero_term_delta, temp1, temp2;
213 std::string header, how;
215 Eigen::MatrixXd onesn, two2np1, one2n, v, y, v1, tempX1, tempX2, xbar, xr, x, xe, xc, xcc, xin, posCopy;
216 std::vector<double> fv, fv1;
217 std::vector<int> idx;
223 header =
" Iteration Func-count min f(x) Procedure";
234 onesn = Eigen::MatrixXd::Ones(1, n);
235 two2np1 = one2n = Eigen::MatrixXd::Zero(1, n);
237 for (
int i = 0; i < n; i++) {
242 v = v1 = Eigen::MatrixXd::Zero(n, n + 1);
247 for (
int i = 0; i < n; i++) {
248 v(i, 0) = posCopy(i);
251 tempdip =
dipfitError(posCopy, matData, sensors, matProjectors);
252 fv[0] = tempdip.
error;
261 zero_term_delta = 0.00025;
262 xin = posCopy.transpose();
264 for (
int j = 0; j < n; j++) {
268 y(j) = (1 + usual_delta) * y(j);
270 y(j) = zero_term_delta;
273 v.col(j + 1).array() = y;
274 posCopy = y.transpose();
275 tempdip =
dipfitError(posCopy, matData, sensors, matProjectors);
276 fv[j + 1] = tempdip.
error;
280 std::vector<HPISortStruct> vecSortStruct;
282 for (
int i = 0; i < static_cast<int>(fv.size()); i++) {
286 vecSortStruct.push_back(structTemp);
289 std::sort(vecSortStruct.begin(), vecSortStruct.end(),
compare);
291 for (
int i = 0; i < static_cast<int>(vecSortStruct.size()); i++) {
292 idx[i] = vecSortStruct[i].idx;
295 for (
int i = 0; i < n + 1; i++) {
296 v1.col(i) = v.col(idx[i]);
303 how =
"initial simplex";
304 itercount = itercount + 1;
307 tempX1 = Eigen::MatrixXd::Zero(1, n);
309 while ((func_evals < iMaxfun) && (itercount < iMaxiter)) {
310 for (
int i = 0; i < n; i++) {
311 tempX1(i) = std::fabs(fv[0] - fv[i + 1]);
314 temp1 = tempX1.maxCoeff();
316 tempX2 = Eigen::MatrixXd::Zero(n, n);
318 for (
int i = 0; i < n; i++) {
319 tempX2.col(i) = v.col(i + 1) - v.col(0);
322 tempX2 = tempX2.array().abs();
324 temp2 = tempX2.maxCoeff();
326 if ((temp1 <= tolf) && (temp2 <= tolx)) {
330 xbar = v.block(0, 0, n, n).rowwise().sum();
333 xr = (1 + rho) * xbar - rho * v.block(0, n, v.rows(), 1);
338 fxr =
dipfitError(x, matData, sensors, matProjectors);
340 func_evals = func_evals + 1;
342 if (fxr.
error < fv[0]) {
344 xe = (1 + rho * chi) * xbar - rho * chi * v.col(v.cols() - 1);
346 fxe =
dipfitError(x, matData, sensors, matProjectors);
347 func_evals = func_evals + 1;
350 v.col(v.cols() - 1) = xe;
354 v.col(v.cols() - 1) = xr;
359 if (fxr.
error < fv[n - 1]) {
360 v.col(v.cols() - 1) = xr;
365 if (fxr.
error < fv[n]) {
367 xc = (1 + psi * rho) * xbar - psi * rho * v.col(v.cols() - 1);
369 fxc =
dipfitError(x, matData, sensors, matProjectors);
370 func_evals = func_evals + 1;
373 v.col(v.cols() - 1) = xc;
375 how =
"contract outside";
381 xcc = (1 - psi) * xbar + psi * v.col(v.cols() - 1);
383 fxcc =
dipfitError(x, matData, sensors, matProjectors);
384 func_evals = func_evals + 1;
385 if (fxcc.
error < fv[n]) {
386 v.col(v.cols() - 1) = xcc;
388 how =
"contract inside";
395 if (how.compare(
"shrink") == 0) {
396 for (
int j = 1; j < n + 1; j++) {
397 v.col(j).array() = v.col(0).array() + sigma * (v.col(j).array() - v.col(0).array());
398 x = v.col(j).array().transpose();
399 tempdip =
dipfitError(x, matData, sensors, matProjectors);
400 fv[j] = tempdip.
error;
407 vecSortStruct.clear();
409 for (
int i = 0; i < static_cast<int>(fv.size()); i++) {
413 vecSortStruct.push_back(structTemp);
416 std::sort(vecSortStruct.begin(), vecSortStruct.end(),
compare);
417 for (
int i = 0; i < static_cast<int>(vecSortStruct.size()); i++) {
418 idx[i] = vecSortStruct[i].idx;
421 for (
int i = 0; i < n + 1; i++) {
422 v1.col(i) = v.col(idx[i]);
428 itercount = itercount + 1;
431 x = v.col(0).transpose();
434 iSimplexNumitr = itercount;