Changeset 3f6abd2 in tol
- Timestamp:
- Jan 31, 2009, 6:58:07 PM (18 years ago)
- Branches:
- 1941-docker-image-to-test, devel, master
- Children:
- 1e41194
- Parents:
- bbf0235
- File:
-
- 1 edited
-
tol/btol/vmatrix_type/vmat_iterative.cpp (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
tol/btol/vmatrix_type/vmat_iterative.cpp
rbbf0235 r3f6abd2 17 17 along with this program; if not, write to the Free Software 18 18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 19 USA. 20 */ 19 USA. */ 21 20 22 21 #if defined(_MSC_VER) … … 25 24 26 25 #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 27 31 28 32 //-------------------------------------------------------------------- … … 39 43 //-------------------------------------------------------------------- 40 44 { 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 } 44 56 int rows=A.Rows(); 45 57 int cols=A.Columns(); 46 58 /* 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())) 49 61 { 50 62 return(x); … … 53 65 if(chop<0) { chop = sqrt(DEpsilon()/cols); } 54 66 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(); 60 72 BVMat p = s; 61 73 BVMat q; … … 131 143 } 132 144 r = r - q*a; 133 s = At*r; 145 //s = At*r; 146 s = (r.T()*A).T(); 134 147 oldS = S; 135 148 S = s.SquaresdSum(); … … 152 165 //-------------------------------------------------------------------- 153 166 { 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 //-------------------------------------------------------------------- 223 BVMat 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 //-------------------------------------------------------------------- 349 BVMat 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.
