295 "Input argument has wrong dimensions: "<< arg.transpose() );
298 gsMatrix<T,_Dim,(_Dim==-1?-1:1)> delta , residual;
304 GISMO_ASSERT( (arg.array()>=supp.col(0).array()).all() &&
305 (arg.array()<=supp.col(1).array()).all(),
306 "Initial point is outside the domain.\n point = "<<arg<<
"\n domain = "<<supp);
309 T rnorm[2]; rnorm[0]=1e100;
314 this->compute(arg,fd);
315 residual = (0==mode?fd.values[0]:fd.values[1]);
317 residual.noalias() = value - scale*residual;
318 rnorm[iter%2] = residual.norm();
320 if(rnorm[iter%2] <= accuracy)
328 jac = scale * fd.jacobian(0);
330 jac = scale * fd.hessian(0);
340 delta.noalias() = jac.partialPivLu().solve( residual );
342 delta.noalias() = jac.inverse() * residual;
345 delta.noalias() =
jac.colPivHouseholderQr().solve(
346 gsMatrix<T>::Identity(n,n)) * residual;
348 const T rr = ( 1==iter ? (T)1.51 : rnorm[(iter-1)%2]/rnorm[iter%2] );
349 damping_factor = rr<1.5 ? math::max((T)0.1 + (rr/99),(rr-(T)0.5)*damping_factor) : math::min((T)1,rr*damping_factor);
366 arg += damping_factor * delta;
371 arg = arg.cwiseMax( supp.col(0) ).cwiseMin( supp.col(1) );
372 if ( delta.norm()<accuracy )
379 }
while (++iter <= max_loop);
381 gsWarn <<
"--- Newton method did not converge after "<< max_loop
382 <<
" iterations. Residual norm: "<< rnorm[max_loop%2]<<
".\n";
388gsVector<T> gsFunction<T>::_argMinOnGrid(
index_t numpts)
const
391 gsMatrix<T> supp = this->support();
394 result = this->parameterCenter();
395 gsGridIterator<T,CUBE> pt(supp, numpts);
396 T val, mval = this->eval(result).value();
399 val = this->eval(*pt).value();
410 result.setZero( domainDim() );
416gsVector<T> gsFunction<T>::_argMinNormOnGrid(
index_t numpts)
const
419 gsMatrix<T> supp = this->support();
422 result = this->parameterCenter();
423 gsGridIterator<T,CUBE> pt(supp, numpts);
424 T val, mval = this->eval(result).squaredNorm();
427 if ( (val = this->eval(*pt).squaredNorm())<mval )
437 result.setZero( domainDim() );
448 T damping_factor)
const
451 "Invalid input values:"<< value.rows()<<
"!="<<targetDim());
452 return newtonRaphson_impl<0>(value,arg,withSupport,accuracy,
453 max_loop,damping_factor);
460 T damping_factor)
const
462 GISMO_ASSERT(1==targetDim(),
"Currently argMin works for scalar functions");
466 if ( 0 != init.size() )
470 result = _argMinOnGrid(20);
473#ifdef gsHLBFGS_ENABLED
474 gsFunctionAdaptor<T> fmin(*
this);
477 gsHLBFGS<T> solver( &fmin );
478 solver.options().setInt(
"MaxIterations",100);
479 solver.options().setInt(
"Verbose",0);
481 solver.solve(result);
482 result = solver.currentDesign();
489 newtonRaphson_impl<1,2>(gsVector<T>::Zero(dd), result,
true,
490 accuracy,max_loop,damping_factor,(T)1);
493 newtonRaphson_impl<1>(gsVector<T>::Zero(dd), result,
true,
494 accuracy,max_loop,damping_factor,(T)1);
505 const T accuracy)
const
508 for (
index_t i = 0; i!= xyz.rows(); ++i)
510 else if (i>k) ind[i-1]=i;
524 xyz = this->eval(uv);
531 index_t k,
const T accuracy)
const
534 for (
index_t i = 0; i!= xyz.rows(); ++i)
536 else if (i>k) ind[i-1]=i;
541 fc.invertPointGrid(git,uv,accuracy,
false);
542 xyz = this->eval(uv);
555 const index_t dim = supp.rows();
561 coordinates(d,0) = supp(d,1);
563 coordinates(d,0) = supp(d,0);
572 const index_t dim = supp.rows();
578 coordinates(d,0) = ( supp(d,1) + supp(d,0) ) / (T)(2);
580 coordinates(d,0) = supp(d,1);
582 coordinates(d,0) = supp(d,0);
587template <
class T>
void
592 this->deriv2_into(u, secDers);
593 const index_t dim = this->domainDim();
594 const index_t nd = dim*(dim+1)/2;
595 result = util::secDerToHessian(secDers.middleCols(coord*nd,nd), dim);
598template <
typename T,
short_t domDim,
short_t tarDim>
599inline void computeAuxiliaryData(
const gsFunction<T> &src, gsMapData<T> & InOut,
int d,
int n)
602 const index_t numPts = InOut.points.cols();
610 if (InOut.side==boundary::none)
611 gsWarn<<
"Computing boundary normal without a valid side.\n";
615 const int dir = InOut.side.direction();
616 InOut.outNormals.resize(n,numPts);
618 if (tarDim!=-1 ? tarDim == domDim : n==d)
620 if ( 1==n ) { InOut.outNormals.setConstant(sgn);
return; }
623 typename gsMatrix<T,domDim,tarDim>::FirstMinorMatrixType minor;
627 for (
index_t p=0; p!=numPts; ++p)
629 const gsAsConstMatrix<T,domDim,tarDim> jacT(InOut.values[1].col(p).data(), d, n);
630 T detJacTcurr = jacT.determinant();
631 if ( math::abs(detJacTcurr) >= 1e-7 )
633 det_sgn = detJacTcurr < 0 ? -1 : 1;
639 gsMatrix<T> parameterCenter = src.parameterCenter(InOut.side);
640 T detJacTcurr = src.jacobian(parameterCenter).determinant();
641 det_sgn = detJacTcurr < 0 ? -1 : 1;
644 for (
index_t p=0; p!=numPts; ++p)
646 const gsAsConstMatrix<T,domDim,tarDim> jacT(InOut.values[1].col(p).data(), d, n);
652 T detJacTcurr = jacT.determinant();
653 det_sgn = math::abs(detJacTcurr) < 1e-7 ? 0 :
654 ( detJacTcurr < 0 ? -1 : 1 );
657 gsMatrix<T> parameterCenter = src.parameterCenter(InOut.side);
658 detJacTcurr = src.jacobian(parameterCenter).determinant();
659 det_sgn = detJacTcurr < 0 ? -1 : 1;
662 GISMO_ENSURE(det_sgn!=0,
"Cannot find a non-zero Jacobian determinant.\n" << InOut.points);
664 T alt_sgn = sgn * det_sgn;
665 for (
int i = 0; i != n; ++i)
667 jacT.firstMinor(dir, i, minor);
668 InOut.outNormals(i,p) = alt_sgn * minor.determinant();
675 gsMatrix<T,domDim,domDim> metric(d,d);
676 gsVector<T,domDim> param(d);
677 typename gsMatrix<T,domDim,domDim>::FirstMinorMatrixType minor;
678 for (
index_t p=0; p!=numPts; ++p)
680 const gsAsConstMatrix<T,domDim,tarDim> jacT(InOut.values[1].col(p).data(), d, n);
681 metric= (jacT*jacT.transpose());
683 for (
int i = 0; i != (domDim!=-1?domDim:d); ++i)
685 metric.firstMinor(dir, i, minor);
686 param(i) = alt_sgn * minor.determinant();
689 InOut.outNormals.col(p)=jacT.transpose()*param/metric.determinant();
699 InOut.measures.resize(1,numPts);
700 if (InOut.side==boundary::none)
702 for (
index_t p = 0; p < numPts; ++p)
704 typename gsAsConstMatrix<T,domDim,tarDim>::Tr
jac =
705 gsAsConstMatrix<T,domDim,tarDim>(InOut.values[1].col(p).data(),d, n).transpose();
706 if ( tarDim!=-1 ? tarDim == domDim : n==d )
707 InOut.measures(0,p) = math::
abs(
jac.determinant());
709 InOut.measures(0,p) = math::sqrt( (
jac.transpose()*jac )
716 const int dir = InOut.side.direction();
717 typename gsMatrix<T,domDim,tarDim>::ColMinorMatrixType minor;
718 InOut.measures.resize(1, numPts);
719 for (
index_t p = 0; p != numPts; ++p)
721 const gsAsConstMatrix<T,domDim,tarDim> jacT(InOut.values[1].col(p).data(), d, n);
722 InOut.measures.at(p) = jacT.row(!dir).norm();
732 InOut.jacInvTr.resize(d*n, numPts);
733 for (
index_t p=0; p!=numPts; ++p)
735 const gsAsConstMatrix<T,domDim,tarDim> jacT(InOut.values[1].col(p).data(), d, n);
737 if ( tarDim!=-1 ? tarDim == domDim : n==d )
738 gsAsMatrix<T,tarDim,domDim>(InOut.jacInvTr.col(p).data(), n, d)
742 gsAsMatrix<T,tarDim,domDim>(InOut.jacInvTr.col(p).data(), n, d)
749 if ( (InOut.flags &
NEED_NORMAL) && (tarDim!=-1 ? tarDim == domDim+1 : n==d+1) )
751 typename gsMatrix<T,domDim,tarDim>::ColMinorMatrixType minor;
752 InOut.normals.resize(n, numPts);
754 for (
index_t p = 0; p != numPts; ++p)
756 const gsAsConstMatrix<T,domDim,tarDim> jacT(InOut.values[1].col(p).data(), d, n);
758 for (
int i = 0; i != tarDim; ++i)
760 jacT.colMinor(i, minor);
761 InOut.normals(i,p) = alt_sgn * minor.determinant();
776 InOut.fundForms.resize(d*d, numPts);
778 for (
index_t p=0; p!=numPts; ++p)
780 const gsAsConstMatrix<T,-1,tarDim> ddT(InOut.values[2].col(p).data(), sz, n);
781 const T nrm = InOut.normals.col(p).norm();
784 InOut.fundForms(0,p) = ddT.row(0).dot(InOut.normals.col(p)) / nrm;
785 InOut.fundForms(3,p) = ddT.row(1).dot(InOut.normals.col(p)) / nrm;
786 InOut.fundForms(1,p) = InOut.fundForms(2,p) =
787 ddT.row(2).dot(InOut.normals.col(p)) / nrm;
825 this->compute(InOut.
points, InOut);
828 std::pair<short_t, short_t> Dim = this->dimensions();
830 GISMO_ASSERT(Dim.first<10,
"Domain dimension is too big");
831 GISMO_ASSERT(Dim.first<=Dim.second,
"Singular map: target dimension is lower then the domain dimension");
832 switch (10 * Dim.second + Dim.first)
835 case 11: computeAuxiliaryData<T,1,1>(*
this, InOut, Dim.first, Dim.second);
break;
836 case 21: computeAuxiliaryData<T,1,2>(*
this, InOut, Dim.first, Dim.second);
break;
841 case 22: computeAuxiliaryData<T,2,2>(*
this, InOut, Dim.first, Dim.second);
break;
842 case 32: computeAuxiliaryData<T,2,3>(*
this, InOut, Dim.first, Dim.second);
break;
847 case 33: computeAuxiliaryData<T,3,3>(*
this, InOut, Dim.first, Dim.second);
break;
853 case 44: computeAuxiliaryData<T,4,4>(*
this, InOut, Dim.first, Dim.second);
break;
854 default: computeAuxiliaryData<T,-1,-1>(*
this, InOut, Dim.first, Dim.second);
break;