Changeset 3f6abd2 in tol


Ignore:
Timestamp:
Jan 31, 2009, 6:58:07 PM (18 years ago)
Author:
Víctor de Buen <vdebuen@…>
Branches:
1941-docker-image-to-test, devel, master
Children:
1e41194
Parents:
bbf0235
Message:

Adding virtual linear operator API of MinimumResidualsSolve

git-svn-id: ​https://www.tol-project.org/svn/tolp/trunk@528 be4846ae-f051-483a-831f-b64e7d08527f

File:
1 edited

Legend:

Unmodified
Added
Removed
  • tol/btol/vmatrix_type/vmat_iterative.cpp

    rbbf0235 r3f6abd2  
    1717   along with this program; if not, write to the Free Software
    1818   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
    19    USA.
    20  */
     19   USA. */
    2120
    2221#if defined(_MSC_VER)
    … …  
    2524
    2625#include <tol/tol_bvmat_impl.h>
     26#include <tol/tol_bvmatgra.h>
     27#include <tol/tol_bdatgra.h>
     28#include <tol/tol_bcodgra.h>
     29#include <tol/tol_blanguag.h>
     30
    2731
    2832//--------------------------------------------------------------------
    … …  
    3943//--------------------------------------------------------------------
    4044{
    41   BVMat x;
    42   int i;
    43   int k;
     45  BVMat x, r;
     46  int i, k;
     47  r.Convert(b0,ESC_blasRdense);
     48  if(!x0.Rows())
     49  {
     50    x = (r.T()*A).T();
     51  }
     52  else
     53  {
     54    x.Convert(x0,ESC_blasRdense);
     55  }
    4456  int rows=A.Rows();
    4557  int cols=A.Columns();
    4658  /* PRECONDITIONS: ENSURING DIMENSIONS */
    47   if(!rows||!cols||!b0.Columns()||!x0.Columns()||
    48      (rows<cols)||(rows!=b0.Rows())||(cols!=x0.Rows()))
     59  if(!rows||!cols||!r.Columns()||!x.Columns()||
     60     (rows<cols)||(rows!=r.Rows())||(cols!=x.Rows()))
    4961  {
    5062    return(x);
    … …  
    5365  if(chop<0) { chop = sqrt(DEpsilon()/cols); }
    5466  double tolerance = chop*chop;
    55   if((rows<cols)||(rows!=b0.Rows())) { return(x0); }
    56   x.Convert(x0,ESC_blasRdense);
    57   BVMat At = A.T();
    58   BVMat r = b0 - A*x;
    59   BVMat s = At*r;
     67  if((rows<cols)||(rows!=r.Rows())) { return(x); }
     68//BVMat At = A.T();
     69  r = r - A*x;
     70//BVMat s = At*r;
     71  BVMat s = (r.T()*A).T();
    6072  BVMat p = s;
    6173  BVMat q;
    … …  
    131143    }
    132144    r = r - q*a;
    133     s  = At*r;
     145  //s  = At*r;
     146    s = (r.T()*A).T();
    134147    oldS = S;
    135148    S  = s.SquaresdSum();
    … …  
    152165//--------------------------------------------------------------------
    153166{
    154   return(BVMat::MinimumResidualsSolve(A,b0,A.T()*b0,chop,maxIter));
    155 }
    156 
    157 
    158 
     167  BVMat x0;
     168  return(BVMat::MinimumResidualsSolve(A,b0,x0,chop,maxIter));
     169}
     170
     171
     172//--------------------------------------------------------------------
     173   static bool CheckOprProd(const BStandardOperator* opr,
     174                            const BText& funName)
     175// Checks if opr have expected API VMatrix(VMatrix x, Real traspose)
     176//--------------------------------------------------------------------
     177{
     178        bool ok = opr &&
     179                  (opr->Grammar() == GraVMatrix()) &&
     180                  (opr->MinArg() == 2) &&
     181                  (opr->MaxArg() == 2) &&
     182                  (opr->GrammarForArg(1) == GraVMatrix())&&
     183                  (opr->GrammarForArg(2) == GraReal());
     184  if(!ok)
     185  {
     186    Error(I2("Invalid declaration","Declaración no válida")+": \n  "+
     187          opr->Grammar()->Name()+" "+opr->Identify()+opr->Arguments()+"\n"+
     188          I2("for linear operator used in","para el operador lineal")+" "+funName+"\n"+
     189          I2("Expected declaration was","La declaración esperada era")+":\n  "+
     190          "VMatrix"+" "+opr->Identify()+"(VMatrix x, Real traspose)");
     191  }
     192  return(ok);
     193}
     194
     195//--------------------------------------------------------------------
     196   static bool OprProd(const BStandardOperator* opr,
     197                       const BVMat& x,
     198                       bool traspose,
     199                       BVMat& y)
     200// Applys linear operator to x and returns y = opr(x,traspose)
     201//--------------------------------------------------------------------
     202{
     203  bool ok=false;
     204  BContensVMat* uX  = new BContensVMat(x);
     205  BContensDat*  uT  = new BContensDat(traspose);
     206  BList*        lst = Cons(uX,NCons(uT));
     207  BUserVMat*    uY  = (BUserVMat*)(opr->Evaluator(lst));
     208  if(uY)
     209  {
     210    ok = true;
     211    y = VMat(uY);
     212    DESTROY(uY);
     213  }
     214  else
     215  {
     216    ok=false;
     217    y.Delete();
     218  }
     219  return(ok);
     220};
     221
     222//--------------------------------------------------------------------
     223BVMat BVMat::MinimumResidualsSolve(BStandardOperator* A,
     224                                   const BVMat& b0,
     225                                   const BVMat& x0,
     226                                   double chop,
     227                                   int maxIter)
     228
     229/*! Solves Ax=b using the Lanczos method from a intial
     230 *  aproximation in a given maximum of iterations and obtaining an
     231 *  standard error less than a given tolerance.
     232 */
     233//--------------------------------------------------------------------
     234{
     235  static BText funName = "MinimumResidualsSolve";
     236  int i, k;
     237  BVMat x, r;
     238  if(!CheckOprProd(A,funName)) { return(x); }
     239  r.Convert(b0,ESC_blasRdense);
     240  if(!x0.Rows())
     241  {
     242    OprProd(A,r,true,x);
     243  }
     244  else
     245  {
     246    x .Convert(x0,ESC_blasRdense);
     247  }
     248  BVMat q;
     249  OprProd(A,x,false, q);
     250//BVMat At = A.T();
     251  r = r - q;
     252//BVMat s = At*r;
     253  BVMat s;
     254  OprProd(A,r,true,s);
     255  BVMat p = s;
     256
     257  int rows = q.Rows();
     258  int cols = p.Rows();
     259  //PRECONDITIONS: ENSURING DIMENSIONS
     260  if(!rows||!cols||!r.Columns()||!x.Columns()||
     261     (rows<cols)||(rows!=r.Rows())||(cols!=x.Rows()))
     262  {
     263    return(x);
     264  }
     265 
     266  if(chop<0) { chop = sqrt(DEpsilon()/cols); }
     267  double tolerance = chop*chop;
     268  if((rows<cols)||(rows!=r.Rows())) { return(x); }
     269
     270  BVMat pa;
     271  BVMat rpa;
     272  double a;
     273  double b;
     274  double q2;
     275  double advance;
     276  double relAdv;
     277  double oldR;
     278  double R=r.FrobeniusNorm();
     279  BDat xNorm=x.FrobeniusNorm();
     280  BDat oldxNorm;
     281  BDat xNormAdvance;
     282  BDat maxpa;
     283  BDat oldMaxpa;
     284  BDat oldS;
     285  BDat S = s.SquaresdSum();
     286  BDat tol = BDat::Tolerance();
     287
     288  for(k=0; k<maxIter;  k++)
     289  {
     290    if(k && !(k%cols))
     291    {
     292      Std(BText("\nBVMat::MinimumResidualsSolve ")+
     293        " iter="+k+
     294        " maxpa="+maxpa+
     295        " S="+S+
     296        " advance="+advance);
     297    }
     298    OprProd(A,p,false,q);
     299    q2 = q.SquaresdSum();
     300    a = S.Value()/q2;
     301    pa = p*a;
     302    oldMaxpa = maxpa;
     303    oldR = R;
     304    R = r.FrobeniusNorm();
     305    oldxNorm = xNorm;
     306    x = x+pa;
     307    xNorm = x.FrobeniusNorm();
     308    xNormAdvance = xNorm-oldxNorm;
     309
     310    maxpa = 0;
     311    for(i=0; i<cols; i++)
     312    {
     313      if(x.GetCell(i,0)!=0)
     314      {
     315        double rpa = fabs(pa.GetCell(i,0)/x.GetCell(i,0));
     316        if(rpa>maxpa) { maxpa = rpa; }
     317      }
     318    }
     319
     320    advance = R-oldR;
     321    relAdv = advance/oldR;
     322    if(k)
     323    {
     324      if(S.IsUnknown()    )
     325      { break; }
     326      if(maxpa.IsUnknown())
     327      { break; }
     328      if(S <= tolerance   )
     329      { break; }
     330/* */
     331      if(1+maxpa-1 == 0   )
     332      { break; }
     333      if(advance >   0    )
     334      { break; }
     335/* */
     336    }
     337    r = r - q*a;
     338  //s  = At*r;
     339    OprProd(A,r,true,s);
     340    oldS = S;
     341    S  = s.SquaresdSum();
     342    b  = S.Value()/oldS.Value();
     343    p = p*b+s;
     344  }
     345  return(x);
     346}
     347
     348//--------------------------------------------------------------------
     349BVMat BVMat::MinimumResidualsSolve(BStandardOperator* A,
     350                                   const BVMat& b0,
     351                                   double chop,
     352                                   int maxIter)
     353
     354/*! Solves Ax=b using the Lanczos method from a intial
     355 *  aproximation in a given maximum of iterations and obtaining an
     356 *  standard error less than a given tolerance.
     357 */
     358//--------------------------------------------------------------------
     359{
     360  BVMat x0;
     361  return(BVMat::MinimumResidualsSolve(A,b0,x0,chop,maxIter));
     362}
     363/* */
Note: See TracChangeset for help on using the changeset viewer.