int bicgstab(const LinearOperator& A, HilbertSpaceX& x, const HilbertSpaceB& b, const Preconditioner& M, Iteration& iter) { typedef typename mtl::Collection<HilbertSpaceX>::value_type Scalar; typedef HilbertSpaceX Vector; Scalar rho_1(0), rho_2(0), alpha(0), beta(0), gamma, omega(0); Vector p(size(x)), phat(size(x)), s(size(x)), shat(size(x)), t(size(x)), v(size(x)), r(size(x)), rtilde(size(x)); r = b - A * x; rtilde = r; while (! iter.finished(r)) { rho_1 = dot(rtilde, r); MTL_THROW_IF(rho_1 == 0.0, unexpected_orthogonality()); if (iter.first()) p = r; else { MTL_THROW_IF(omega == 0.0, unexpected_orthogonality()); beta = (rho_1 / rho_2) * (alpha / omega); p = r + beta * (p - omega * v); } phat = solve(M, p); v = A * phat; gamma = dot(rtilde, v); MTL_THROW_IF(gamma == 0.0, unexpected_orthogonality()); alpha = rho_1 / gamma; s = r - alpha * v; if (iter.finished(s)) { x += alpha * phat; break; } shat = solve(M, s); t = A * shat; omega = dot(t, s) / dot(t, t); x += omega * shat + alpha * phat; r = s - omega * t; rho_2 = rho_1; ++iter; } return iter; }
int fsm(const LinearOperator& H, VectorSpace& phi, EigenValue eps, Damping alpha, Iteration& iter) { VectorSpace v1(H * phi - eps * phi); for (; !iter.finished(v1); ++iter) { VectorSpace v2(H * v1 - eps * v1); phi-= alpha * v2; phi/= two_norm(phi); v1= H * phi - eps * phi; } return iter; }
int bicg(const LinearOperator &A, Vector &x, const Vector &b, const Preconditioner &M, Iteration& iter) { using mtl::conj; typedef typename mtl::Collection<Vector>::value_type Scalar; Scalar rho_1(0), rho_2(0), alpha(0), beta(0); Vector r(b - A * x), z(size(x)), p(size(x)), q(size(x)), r_tilde(r), z_tilde(size(x)), p_tilde(size(x)), q_tilde(size(x)); while (! iter.finished(r)) { z= solve(M, r); z_tilde= adjoint_solve(M, r_tilde); rho_1= dot(z_tilde, z); if (rho_1 == 0.) { iter.fail(2, "bicg breakdown"); break; } if (iter.first()) { p= z; p_tilde= z_tilde; } else { beta= rho_1 / rho_2; p= z + beta * p; p_tilde= z_tilde + conj(beta) * p_tilde; } q= A * p; q_tilde= adjoint(A) * p_tilde; alpha= rho_1 / dot(p_tilde, q); x+= alpha * p; r-= alpha * q; r_tilde-= conj(alpha) * q_tilde; rho_2= rho_1; ++iter; } return iter.error_code(); }
Normalization::Normalization(QWidget *parent, Matrix* in, QVector<QVector<Matrix *> *> *rGraphs): QWidget(parent), pInMain(in) { if (parent != nullptr) connect(this, SIGNAL(loopedMatrix()), parent, SIGNAL(loopedMatrix())); cout << "OKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOKOK" << "\n"; Iteration *b; Matrix* pRes=pInMain; while (1) { b=new Iteration(pRes); delete pRes; rGraphs->append( b->getGraphs()); if (b->getArrayIsNull() || b->isLooped()) { if (b->isLooped()) { QMessageBox::warning(this, tr("Ошибка"), tr("Введенные связи образуют кольцо, нормализация не возможна. Проверьте корректность введеных данных.")); emit loopedMatrix(); } delete b; return; } pRes=b->getRemains(); delete b; } }
int cg(const LinearOperator& A, HilbertSpace& x, const HilbertSpace& b, Iteration& iter) { typedef HilbertSpace TmpVec; typedef typename mtl::Collection<HilbertSpace>::value_type Scalar; Scalar rho, rho_1, alpha, beta; TmpVec p(size(x)), q(size(x)), r(size(x)), z(size(x)); // r = b - A*x; r = b; r -= A*x; while (! iter.finished(r)) { rho = dot(r, r); if (iter.first()) p = r; else { beta = rho / rho_1; p = r + beta * p; } q = A * p; alpha = rho / dot(p, q); x += alpha * p; r -= alpha * q; rho_1 = rho; ++iter; } return iter.error_code(); }
int qmr(const Matrix& A, Vector& x, const Vector& b, LeftPreconditioner& L, const RightPreconditioner& R, Iteration& iter) { typedef typename mtl::Collection<Vector>::value_type Scalar; typedef typename mtl::Collection<Vector>::size_type Size; if (size(b) == 0) throw mtl::logic_error("empty rhs vector"); const Scalar zero= math::zero(b[0]), one= math::one(b[0]); Scalar rho_1, gamma(one), gamma_1, theta(zero), theta_1, eta(-one), delta, ep(one), beta; Size n(size(x)); Vector r(b - A * x), v_tld(r), y(solve(L, v_tld)), w_tld(r), z(adjoint_solve(R,w_tld)), v(n), w(n), y_tld(n), z_tld, p, q, p_tld, d, s; if (iter.finished(r)) return iter; Scalar rho = two_norm(y), xi = two_norm(z); while(! iter.finished(rho)) { if (rho == zero) return iter.fail(1, "qmr breakdown, rho=0 #1"); if (xi == zero) return iter.fail(2, "qmr breakdown, xi=0 #2"); v= v_tld / rho; y/= rho; w= w_tld / xi; z/= xi; delta = dot(z,y); if (delta == zero) return iter.fail(3, "qmr breakdown, delta=0 #3"); y_tld = solve(R,y); z_tld = adjoint_solve(L,z); if (iter.first()) { p = y_tld; q = z_tld; } else { p = y_tld - ((xi * delta) / ep) * p; q = z_tld - ((rho* delta) / ep) * q; } p_tld = A * p; ep = dot(q, p_tld); if (ep == zero) return iter.fail(4, "qmr breakdown ep=0 #4"); beta= ep / delta; if (beta == zero) return iter.fail(5, "qmr breakdown beta=0 #5"); v_tld = p_tld - beta * v; y = solve(L,v_tld); rho_1 = rho = two_norm(y); w_tld= trans(A)*q - beta*w; z = adjoint_solve(R, w_tld); xi = two_norm(z); gamma_1 = gamma; theta_1 = theta; theta = rho / (gamma_1 * beta); gamma = one / (sqrt(one + theta * theta)); if (gamma == zero) return iter.fail(6, "qmr breakdown gamma=0 #6"); eta= -eta * rho_1 * gamma * gamma / (beta * gamma_1 * gamma_1); if (iter.first()) { d= eta * p; s= eta * p_tld; } else { d= eta * p + (theta_1 * theta_1 * gamma * gamma) * d; s= eta * p_tld + (theta_1 * theta_1 * gamma * gamma) * s; } x += d; r -= s; ++iter; } return iter; }
int bicgstab_ell(const LinearOperator &A, Vector &x, const Vector &b, const LeftPreconditioner &L, const RightPreconditioner &R, Iteration& iter, size_t l) { mtl::vampir_trace<7006> tracer; using mtl::size; using mtl::irange; using mtl::imax; using mtl::matrix::strict_upper; typedef typename mtl::Collection<Vector>::value_type Scalar; typedef typename mtl::Collection<Vector>::size_type Size; if (size(b) == 0) throw mtl::logic_error("empty rhs vector"); const Scalar zero= math::zero(Scalar()), one= math::one(Scalar()); Vector x0(resource(x)), y(resource(x)); mtl::vector::dense_vector<Vector> r_hat(l+1,Vector(resource(x))), u_hat(l+1,Vector(resource(x))); // shift problem x0= zero; r_hat[0]= b; if (two_norm(x) != zero) { r_hat[0]-= A * x; x0= x; x= zero; } Vector r0_tilde(r_hat[0]/two_norm(r_hat[0])); y= solve(L, r_hat[0]); r_hat[0]= y; u_hat[0]= zero; Scalar rho_0(one), rho_1(zero), alpha(zero), Gamma(zero), beta(zero), omega(one); mtl::matrix::dense2D<Scalar> tau(l+1, l+1); mtl::vector::dense_vector<Scalar> sigma(l+1), gamma(l+1), gamma_a(l+1), gamma_aa(l+1); while (! iter.finished(r_hat[0])) { ++iter; rho_0= -omega * rho_0; for (Size j= 0; j < l; ++j) { rho_1= dot(r0_tilde, r_hat[j]); beta= alpha * rho_1/rho_0; rho_0= rho_1; for (Size i= 0; i <= j; ++i) u_hat[i]= r_hat[i] - beta * u_hat[i]; y= A * Vector(solve(R, u_hat[j])); u_hat[j+1]= solve(L, y); Gamma= dot(r0_tilde, u_hat[j+1]); alpha= rho_0 / Gamma; for (Size i= 0; i <= j; ++i) r_hat[i]-= alpha * u_hat[i+1]; if (iter.finished(r_hat[j])) { x= solve(R, x); x+= x0; return iter; } r_hat[j+1]= solve(R, r_hat[j]); y= A * r_hat[j+1]; r_hat[j+1]= solve(L, y); x+= alpha * u_hat[0]; } // mod GS (MR part) irange i1m(1, imax); mtl::vector::dense_vector<Vector> r_hat_tail(r_hat[i1m]); tau[i1m][i1m]= orthogonalize_factors(r_hat_tail); for (Size j= 1; j <= l; ++j) gamma_a[j]= dot(r_hat[j], r_hat[0]) / tau[j][j]; gamma[l]= gamma_a[l]; omega= gamma[l]; if (omega == zero) return iter.fail(3, "bicg breakdown #2"); // is this something like a tri-solve? for (Size j= l-1; j > 0; --j) { Scalar sum= zero; for (Size i=j+1;i<=l;++i) sum += tau[j][i] * gamma[i]; gamma[j] = gamma_a[j] - sum; } gamma_aa[irange(1, l)]= strict_upper(tau[irange(1, l)][irange(1, l)]) * gamma[irange(2, l+1)] + gamma[irange(2, l+1)]; x+= gamma[1] * r_hat[0]; r_hat[0]-= gamma_a[l] * r_hat[l]; u_hat[0]-= gamma[l] * u_hat[l]; for (Size j=1; j < l; ++j) { u_hat[0] -= gamma[j] * u_hat[j]; x+= gamma_aa[j] * r_hat[j]; r_hat[0] -= gamma_a[j] * r_hat[j]; } } x= solve(R, x); x+= x0; // convert to real solution and undo shift return iter; }