64 using namespace INVERSELIB;
84 Eigen::RowVectorXd vecCurrentCoil = this->m_coilPos;
85 Eigen::VectorXd vecCurrentData = this->m_sensorData;
86 SensorSet currentSensors = this->m_sensors;
89 int iMaxiter = m_iMaxIterations;
90 int iSimplexNumitr = 0;
94 2 * iMaxiter * vecCurrentCoil.cols(),
104 this->m_matProjector);
106 this->m_errorInfo.numIterations = iSimplexNumitr;
112 Eigen::MatrixXd matPnt,
113 Eigen::MatrixXd matOri)
117 Eigen::MatrixXd r, r2, r5, x, y, z, mx, my, mz, Tx, Ty, Tz, lf;
119 iNchan = matPnt.rows();
122 matPnt.array().col(0) -=matPos(0);
123 matPnt.array().col(1) -=matPos(1);
124 matPnt.array().col(2) -=matPos(2);
126 r = matPnt.array().square().rowwise().sum().sqrt();
128 r2 = r5 = x = y = z = mx = my = mz = Tx = Ty = Tz = lf = Eigen::MatrixXd::Zero(iNchan,3);
130 for(
int i = 0;i < iNchan;i++) {
131 r2.row(i).array().fill(pow(r(i),2));
132 r5.row(i).array().fill(pow(r(i),5));
135 for(
int i = 0;i < iNchan;i++) {
136 x.row(i).array().fill(matPnt(i,0));
137 y.row(i).array().fill(matPnt(i,1));
138 z.row(i).array().fill(matPnt(i,2));
141 mx.col(0).array().fill(1);
142 my.col(1).array().fill(1);
143 mz.col(2).array().fill(1);
145 Tx = 3 * x.cwiseProduct(matPnt) - mx.cwiseProduct(r2);
146 Ty = 3 * y.cwiseProduct(matPnt) - my.cwiseProduct(r2);
147 Tz = 3 * z.cwiseProduct(matPnt) - mz.cwiseProduct(r2);
149 for(
int i = 0;i < iNchan;i++) {
150 lf(i,0) = Tx.row(i).dot(matOri.row(i));
151 lf(i,1) = Ty.row(i).dot(matOri.row(i));
152 lf(i,2) = Tz.row(i).dot(matOri.row(i));
155 for(
int i = 0;i < iNchan;i++) {
156 for(
int j = 0;j < 3;j++) {
157 lf(i,j) = u0 * lf(i,j)/(4 * M_PI * r5(i,j));
169 Eigen::MatrixXd matPnt, matOri, matLf;
170 matPnt = sensors.rmag();
171 matOri = sensors.cosmag();
181 const Eigen::MatrixXd& matData,
183 const Eigen::MatrixXd& matProjectors)
187 Eigen::MatrixXd matLfSensor, matDif;
188 Eigen::MatrixXd matLf(matData.size(),3);
189 int iNp = sensors.np();
195 for(
int i = 0; i < sensors.ncoils(); i++){
196 matLf.row(i) = sensors.w(i) * matLfSensor.block(i*iNp,0,iNp,matLfSensor.cols());
204 matDif = matData - matProjectors * matLf * e.moment;
206 e.error = matDif.array().square().sum()/matData.array().square().sum();
217 return (a.base_arr < b.base_arr);
226 const Eigen::MatrixXd& matData,
227 const Eigen::MatrixXd& matProjectors,
231 double tolx, tolf, rho, chi, psi, sigma, func_evals, usual_delta, zero_term_delta, temp1, temp2;
232 std::string header, how;
233 int n, itercount, prnt;
234 Eigen::MatrixXd onesn, two2np1, one2n, v, y, v1, tempX1, tempX2, xbar, xr, x, xe, xc, xcc, xin,posCopy;
235 std::vector <double> fv, fv1;
236 std::vector <int> idx;
240 tolx = tolf = m_fAbortError;
250 header =
" Iteration Func-count min f(x) Procedure";
257 rho = 1; chi = 2; psi = 0.5; sigma = 0.5;
258 onesn = Eigen::MatrixXd::Ones(1,n);
259 two2np1 = one2n = Eigen::MatrixXd::Zero(1,n);
261 for(
int i = 0;i < n;i++) {
266 v = v1 = Eigen::MatrixXd::Zero(n, n+1);
271 for(
int i = 0;i < n; i++) {
275 tempdip =
dipfitError(posCopy, matData, sensors, matProjectors);
276 fv[0] = tempdip.error;
285 zero_term_delta = 0.00025;
286 xin = posCopy.transpose();
288 for(
int j = 0;j < n;j++) {
292 y(j) = (1 + usual_delta) * y(j);
294 y(j) = zero_term_delta;
297 v.col(j+1).array() = y;
298 posCopy = y.transpose();
299 tempdip =
dipfitError(posCopy, matData, sensors, matProjectors);
300 fv[j+1] = tempdip.error;
304 std::vector<HPISortStruct> vecSortStruct;
306 for (
int i = 0; i < fv.size(); i++) {
308 structTemp.base_arr = fv[i];
310 vecSortStruct.push_back(structTemp);
313 std::sort(vecSortStruct.begin(), vecSortStruct.end(),
compare);
315 for (
int i = 0; i < vecSortStruct.size(); i++) {
316 idx[i] = vecSortStruct[i].idx;
319 for (
int i = 0;i < n+1;i++) {
320 v1.col(i) = v.col(idx[i]);
326 how =
"initial simplex";
327 itercount = itercount + 1;
330 tempX1 = Eigen::MatrixXd::Zero(1,n);
332 while ((func_evals < iMaxfun) && (itercount < iMaxiter)) {
334 for (
int i = 0;i < n;i++) {
335 tempX1(i) = std::fabs(fv[0] - fv[i+1]);
338 temp1 = tempX1.maxCoeff();
340 tempX2 = Eigen::MatrixXd::Zero(n,n);
342 for(
int i = 0;i < n;i++) {
343 tempX2.col(i) = v.col(i+1) - v.col(0);
346 tempX2 = tempX2.array().abs();
348 temp2 = tempX2.maxCoeff();
350 if((temp1 <= tolf) && (temp2 <= tolx)) {
354 xbar = v.block(0,0,n,n).rowwise().sum();
357 xr = (1+rho) * xbar - rho * v.block(0,n,v.rows(),1);
362 fxr =
dipfitError(x, matData, sensors, matProjectors);
364 func_evals = func_evals+1;
366 if (fxr.error < fv[0]) {
368 xe = (1 + rho * chi) * xbar - rho * chi * v.col(v.cols()-1);
370 fxe =
dipfitError(x, matData, sensors, matProjectors);
371 func_evals = func_evals+1;
373 if(fxe.error < fxr.error) {
374 v.col(v.cols()-1) = xe;
378 v.col(v.cols()-1) = xr;
384 if(fxr.error < fv[n-1]) {
385 v.col(v.cols()-1) = xr;
390 if(fxr.error < fv[n]) {
392 xc = (1 + psi * rho) * xbar - psi * rho * v.col(v.cols()-1);
394 fxc =
dipfitError(x, matData, sensors, matProjectors);
395 func_evals = func_evals + 1;
397 if(fxc.error <= fxr.error) {
398 v.col(v.cols()-1) = xc;
400 how =
"contract outside";
406 xcc = (1 - psi) * xbar + psi * v.col(v.cols()-1);
408 fxcc =
dipfitError(x, matData, sensors, matProjectors);
409 func_evals = func_evals+1;
410 if(fxcc.error < fv[n]) {
411 v.col(v.cols()-1) = xcc;
413 how =
"contract inside";
420 if(how.compare(
"shrink") == 0) {
421 for(
int j = 1;j < n+1;j++) {
422 v.col(j).array() = v.col(0).array() + sigma * (v.col(j).array() - v.col(0).array());
423 x = v.col(j).array().transpose();
424 tempdip =
dipfitError(x,matData, sensors, matProjectors);
425 fv[j] = tempdip.error;
432 vecSortStruct.clear();
434 for (
int i = 0; i < fv.size(); i++) {
436 structTemp.base_arr = fv[i];
438 vecSortStruct.push_back(structTemp);
441 std::sort(vecSortStruct.begin(), vecSortStruct.end(),
compare);
442 for (
int i = 0; i < vecSortStruct.size(); i++) {
443 idx[i] = vecSortStruct[i].idx;
446 for (
int i = 0;i < n+1;i++) {
447 v1.col(i) = v.col(idx[i]);
453 itercount = itercount + 1;
456 x = v.col(0).transpose();
459 iSimplexNumitr = itercount;