void MasterElementV<METRAITS>::JxW( const Mapping<typename ME2MPTraits<METRAITS>::value> *mapping, const mdata_type mdata[], const intgRule *intg, mdata_type result[]) const { std::vector<mdata_type> Jx(intg->npoints()); mapping->Jx(intg->npoints(), mdata, intg->locations(), &Jx[0]); for (UInt i = 0; i < intg->npoints(); i++) result[i] = intg->weights()[i]*Jx[i]; }
static void residual(const MODEL::Properties& p, JM flux_jacob[], RV& res) { const Real gamma_minus_3 = p.gamma - 3.; const Real uu = p.u * p.u; const Real uv = p.u * p.v; const Real uw = p.u * p.w; const Real vv = p.v * p.v; const Real vw = p.v * p.w; const Real ww = p.w * p.w; JM& Jx = flux_jacob[XX]; // Jx(0,0) = 0.0; Jx(0,1) = 1.0; // Jx(0,2) = 0.0; // Jx(0,3) = 0.0; // Jx(0,4) = 0.0; Jx(1,0) = p.half_gm1_v2 - uu; Jx(1,1) = -gamma_minus_3*p.u; Jx(1,2) = -p.gamma_minus_1*p.v; Jx(1,3) = -p.gamma_minus_1*p.w; Jx(1,4) = p.gamma_minus_1; Jx(2,0) = -uv; Jx(2,1) = p.v; Jx(2,2) = p.u; // Jx(2,3) = 0.0; // Jx(2,4) = 0.0; Jx(3,0) = -uw; Jx(3,1) = p.w; // Jx(3,2) = 0.0; Jx(3,3) = p.u; // Jx(3,4) = 0.0; Jx(4,0) = p.u*(p.half_gm1_v2 - p.H); Jx(4,1) = -p.gamma_minus_1*uu + p.H; Jx(4,2) = -p.gamma_minus_1*uv; Jx(4,3) = -p.gamma_minus_1*uw; Jx(4,4) = p.gamma*p.u; JM& Jy = flux_jacob[YY]; // Jy(0,0) = 0.0; // Jy(0,1) = 0.0; Jy(0,2) = 1.0; // Jy(0,3) = 0.0; // Jy(0,4) = 0.0; Jy(1,0) = -uv; Jy(1,1) = p.v; Jy(1,2) = p.u; // Jy(1,3) = 0.0; // Jy(1,4) = 0.0; Jy(2,0) = p.half_gm1_v2 - vv; Jy(2,1) = -p.gamma_minus_1*p.u; Jy(2,2) = -gamma_minus_3*p.v; Jy(2,3) = -p.gamma_minus_1*p.w; Jy(2,4) = p.gamma_minus_1; Jy(3,0) = -vw; // Jy(3,1) = 0.0; Jy(3,2) = p.w; Jy(3,3) = p.v; // Jy(3,4) = 0.0; Jy(4,0) = p.v*(p.half_gm1_v2 - p.H); Jy(4,1) = -p.gamma_minus_1*uv; Jy(4,2) = -p.gamma_minus_1*vv + p.H; Jy(4,3) = -p.gamma_minus_1*vw; Jy(4,4) = p.gamma*p.v; JM& Jz = flux_jacob[ZZ]; // Jz(0,0) = 0.0; // Jz(0,1) = 0.0; // Jz(0,2) = 0.0; Jz(0,3) = 1.0; // Jz(0,4) = 0.0; Jz(1,0) = -uw; Jz(1,1) = p.w; // Jz(1,2) = 0.0; Jz(1,3) = p.u; // Jz(1,4) = 0.0; Jz(2,0) = -vw; // Jz(2,1) = 0.0; Jz(2,2) = p.w; Jz(2,3) = p.v; // Jz(2,4) = 0.0; Jz(3,0) = p.half_gm1_v2 - ww; Jz(3,1) = -p.gamma_minus_1*p.u; Jz(3,2) = -p.gamma_minus_1*p.v; Jz(3,3) = -gamma_minus_3*p.w; Jz(3,4) = p.gamma_minus_1; Jz(4,0) = p.w*(p.half_gm1_v2 - p.H); Jz(4,1) = -p.gamma_minus_1*uw; Jz(4,2) = -p.gamma_minus_1*vw; Jz(4,3) = -p.gamma_minus_1*ww + p.H; Jz(4,4) = p.gamma*p.w; res = Jx * p.grad_vars.col(XX) + Jy * p.grad_vars.col(YY) + Jz * p.grad_vars.col(ZZ); }
// Simple Gauss-Newton method for ARMA(1,1) MLE // y: observation // WolfCoe: Wolfe condition coefficienti // LineSize: line search step size // FuncTol: function value tolerance // OptiTol: first order tolerance // StepTol: step tolerance // MaxIter: total number of iterations void ARMA11::fit_mle(vec y, double WolfCoe, double LineSize, double FuncTol, double OptiTol, double StepTol, int MaxIter) { // Set initial parameters as method of moments estimates ARMA11 temp(mu, phi, psi, sigma); vec x = temp.residual(y); // Initialize other parameters ARMA11 temp_next = temp; vec x_next = x; double alpha; mat J(3,y.n_elem); vec Jx(3); vec p(3); double L; double L_next; double L_next_approx; // Print iteration info cout.precision(5); cout << setw(5) << "Iter" << setw(8) << "Alpha" << setw(10) << "Grad" << setw(10) << "FuncDiff" << setw(10) << "StepSize" << setw(10) << "LLH" << setw(10) << endl; for (int k=0; k<MaxIter; k++) { // Compute Jacobian matrix J = temp.Jacobian(x,y); Jx = J*x; if (k>1 && (norm(Jx,2)<OptiTol || abs(L_next-L)/abs(L)<FuncTol || norm(alpha*p,2)<StepTol)) { break; } // Gauss-Newton direction // Approxmiate Hessian with J*J' for least square problems p = -solve(J*J.t(),Jx); alpha = 1.0; // Update next parameters temp_next.mu = temp.mu+alpha*p[0]; temp_next.phi = temp.phi+alpha*p[1]; temp_next.psi = temp.psi+alpha*p[2]; x_next = temp_next.residual(y); // Minus log-likelihood function L = L_next; L_next = 0.5*dot(x_next,x_next); // Taylor expansion of L_next L_next_approx = 0.5*dot(x,x)+WolfCoe*alpha*dot(p,Jx); // Line search step size alpha // Wolfe condition: L_next<=L_next_approx while (L_next>L_next_approx) { alpha = LineSize*alpha; temp_next.mu = temp.mu+alpha*p[0]; temp_next.phi = temp.phi+alpha*p[1]; temp_next.psi = temp.psi+alpha*p[2]; x_next = temp_next.residual(y); L_next = 0.5*dot(x_next,x_next); L_next_approx = 0.5*dot(x,x)+WolfCoe*alpha*dot(p,Jx); } temp = temp_next; x = x_next; if (k>0) { cout << setw(5) << fixed << k << setw(8) << fixed << alpha << setw(10) << fixed << norm(Jx,2) << setw(10) << fixed << (L_next-L)/abs(L) << setw(10) << fixed << norm(alpha*p,2) << setw(10) << fixed << L_next << endl; } } mu = temp.mu; phi = temp.phi; psi = temp.psi; sigma = sqrt(dot(x,x)/y.n_elem); }