Adjoint approach to optimization Praveen. C praveen@math.tifrbng.res.in Tata Institute of Fundamental Research Center for Applicable Mathematics Bangalore 560065 http://math.tifrbng.res.in Health, Safety and Environment Group BARC 6-7 October, 2010 Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 1 / 58
Outline Minimum of a function Constrained minimization Finite difference approach Adjoint approach Automatic differentiation Example Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 2 / 58
Minimum of a function f(x) f'(x 0 )=0 x 0 x Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 3 / 58
Steepest descent method x 2 grad f(x 1,x 2 ) x 1 x n+1 = x n s n f(x n ) Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 4 / 58
Objectives and controls Objective function J(α) = J(α, u) mathematical representation of system performance Control variables α Parametric controls α R n Infinite dimensional controls α : X Y Shape α set of admissible shapes State variable u: solution of an ODE or PDE R(α, u) = 0 u = u(α) Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 5 / 58
Gradient-based minimization: blackbox/fd approach Initialize β 0, n = 0 For n = 0,..., N iter Solve R(β n, Q n ) = 0 For j = 1,..., N min I(β, Q(β)) β RN β n (j) = [β n 1,..., β n j + β j,..., β n N ] Solve R(β n (j), Q n (j)) = 0 di dβ j I(β n (j),qn (j) ) I(βn,Q n ) β j Steepest descent step Cost of FD-based steepest-descent β n+1 = β n s n di dβ (βn ) Cost = O(N + 1)N iter = O(N + 1)O(N) = O(N 2 ) Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 6 / 58
Accuracy of FD: Choice of step size d dx f(x 0) = f(x 0 + δ) f(x 0 ) + O(δ) δ In principle, if we choose a small δ, we reduce the error. But computers have finite precision. Instead of f(x 0 ) the computers gives f(x 0 ) + O(ɛ) where ɛ = machine precision. [f(x 0 + δ) + O(ɛ)] [f(x 0 ) + O(ɛ)] δ = d dx f(x ɛ 0) + C 2 δ + C 1 }{{ δ} Total error = f(x 0 + δ) f(x 0 ) δ, C 1, C 2 depend on f, x 0, precision + C 1 ɛ δ Total error is least when δ = δ opt = C 3 ɛ, C3 = C 1 /C 2 Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 7 / 58
Accuracy of FD: Choice of step size Error Precision ɛ δ opt Single 10 8 10 4 Double 10 16 10 8 C 1 δ C 2 ǫ/δ See: Brian J. McCartin, Seven Deadly Sins of Numerical Computation The American Mathematical Monthly, Vol. 105, No. 10 (Dec., 1998), pp. 929-941 δ opt δ Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 8 / 58
Drag gradient using FD (Samareh) Errors in Finite Difference Approximations 10 1 Mid chord % Error 10 0 10-1 10-2 10-3 10-4 10-5 10-6 Round!off LE Sweep2 Tip chord LE sweep3 Twist (root) Twist (mid) Twist (tip) Truncation Twist (root) Twist (mid) Mid chord LE Sweep2 LE Sweep3 Tip chord Twist (tip) 10-9 10-8 10-7 10-6 10-5 10-4 10-3 10-2 10-1 Scaled Step Size Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 9 / 58
Iterative problems I(β, Q), where R(β, Q) = 0 Q is implicitly defined, require an iterative solution method. Assume a Q 0 and iterate Q n Q n+1 until R(β, Q n ) TOL If TOL is too small, need too many iterations Many problems, we cannot reduce R(β, Q n ) to small values This means that numerical value of I will be noisy Finite difference will contain too much error, and is useless RAE5243 airfoil, Mach=0.68, Re=19 million, AOA=2.5 deg. iter Lift Drag 41496 0.824485788042416 1.627593747613790E-002 41497 0.824485782714867 1.627593516695762E-002 41498 0.824485777387834 1.627593285794193E-002 41499 0.824485772061306 1.627593054909022E-002 41500 0.824485766735297 1.627592824040324E-002 Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 10 / 58
Complex variable method f(x 0 + iδ) = f(x 0 ) + iδf (x 0 ) + O(δ 2 ) + io(δ 3 ) f (x 0 ) = 1 δ imag[f(x 0 + iδ)] + O(δ 2 ) No roundoff error We can take δ to be very small, δ = 10 20 Can be easily implemented fortran: redeclare real variables as complex matlab: no change Iterative problems: β β + i β Obtain Q = Q(β + i β) by solving R(β + i β, Q) = 0 Then gradient I (β) 1 imag[i(β + i β, Q(β + i β)] β Computational cost is O(N 2 ) or higher (due to complex arithmetic) Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 11 / 58
Objectives and controls Objective function J(α) = J(α, u) mathematical representation of system performance Control variables α Parametric controls α R n Infinite dimensional controls α : X Y Shape α set of admissible shapes State variable u: solution of an ODE or PDE R(α, u) = 0 Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 12 / 58
Mathematical formulation Constrained minimization problem Find δα such that δj < 0 min α J(α, u) subject to R(α, u) = 0 δj = J J δα + α u δu = J J u δα + = [ α J α + J u u α δα u α ] δα =: Gδα Steepest descent δα = ɛg δj = ɛgg = ɛ G 2 < 0 Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 13 / 58
Mathematical formulation Constrained minimization problem Find δα such that δj < 0 min α J(α, u) subject to R(α, u) = 0 δj = J J δα + α u δu = J J u δα + = [ α J α + J u u α δα u α ] δα =: Gδα Steepest descent δα = ɛg δj = ɛgg = ɛ G 2 < 0 Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 14 / 58
Sensitivity approach Linearized state equation R(α, u) = 0 or R R δα + α u δu = 0 R u u α = R α Solve sensitivity equation iteratively, e.g., Gradient u t α + R u u α = R α dj dα = J α + J u u α Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 15 / 58
Sensitivity approach: Computational cost n design variables: α = (α 1,..., α n ) Solve primal problem R(α, u) = 0 to get u(α) For i = 1,..., n Solve sensitivity equation wrt αi R u u = R α i α i Compute derivative wrt αi dj = J + J dα i α i u u α i One primal equation, n sensitivity equations Computational cost = n + 1 Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 16 / 58
Adjoint approach We have δj = J J R R δα + δu and δα + α u α u δu = 0 Introduce a new unknown v δj = J ( ) J R R δα + δu + v δα + α u α u δu ( ) ( ) J R J R = + v δα + + v δu α α u u Adjoint equation Iterative solution ( ) R ( ) J v = u u v t + ( ) R v = u ( ) J u Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 17 / 58
Adjoint approach: Computational cost n design variables: α = (α 1,..., α n ) Solve primal problem R(α, u) = 0 to get u(α) Solve adjoint problem For i = 1,..., n Compute derivative wrt αi ( ) R ( ) J v = u u dj = J + v R dα i α i α i One primal equation, one adjoint equation Computational cost = 2, independent of n Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 18 / 58
Adjoint: Two approaches Continuous or differentiate-discretize PDE Discrete or discretize-differentiate PDE Adjoint PDE Discrete PDE Discrete adjoint Discrete adjoint Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 19 / 58
Techniques for computing gradients Hand differentiation Finite difference method Complex variable method Automatic Differentiation (AD) Computer code to compute J(α, u) and R(α, u) Chain rule of differentiation Generates a code to compute derivatives ADIFOR, ADOLC, ODYSEE, TAMC, TAF, TAPENADE see http://www.autodiff.org Code for J(α, u) α AD tool Code for J α Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 20 / 58
Derivatives Given a program P computing a function F F : R m R n X Y build a program that computes derivatives of F X : independent variables Y : dependent variables Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 21 / 58
Derivatives [ ] Yj Jacobian matrix: J = X i Directional or tangent derivative Ẏ = JẊ Adjoint mode X = J Ȳ Gradients (n = 1 output) [ ] Y J = = Y X i Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 22 / 58
Forward differentiation Program P is a sequence of computations F k T 0 = X, given k th line t k = F k (T k 1 ), T k = Function is a composition [ Tk 1 F = F p F p 1... F 2 F 1 Chain rule Ẏ = F (X)Ẋ = F p(t p 1 )F p 1(T p 2 )... F 2(T 1 )F 1(T 0 )Ẋ X, Ẋ Y, Ẏ cost(ẏ ) = 4 cost(y ) t k ] Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 23 / 58
Differentiation: Example A simple example f = (xy + sin x + 4)(3y 2 + 6) Computer code, f = t 10 t1 = x t 2 = y t 3 = t 1 t 2 t 4 = sin t 1 t 5 = t 3 + t 4 t 6 = t 5 + 4 t 7 = t 2 2 t 8 = 3t 7 t 9 = t 8 + 6 t 10 = t 6 t 9 Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 24 / 58
F77 code: costfunc.f s ubroutine c o s t f u n c ( x, y, f ) t1 = x t2 = y t3 = t1 t2 t4 = s i n ( t1 ) t5 = t3 + t4 t6 = t5 + 4 t7 = t2 2 t8 = 3.0 t7 t9 = t8 + 6. 0 t10 = t6 t9 f = t10 end Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 25 / 58
Differentiation: Direct mode Apply chain rule of differentiation t 1 = x ṫ 1 = ẋ t 2 = y ṫ 2 = ẏ t 3 = t 1 t 2 ṫ 3 = ṫ 1 t 2 + t 1 ṫ 2 t 4 = sin(t 1 ) ṫ 4 = cos(t 1 )ṫ 1 t 5 = t 3 + t 4 ṫ 5 = ṫ 3 + ṫ 4 t 6 = t 5 + 4 ṫ 6 = ṫ 5 t 7 = t 2 2 ṫ 7 = t 8 = 3t 7 ṫ 8 = 2t 2 ṫ 2 3ṫ 7 t 9 = t 8 + 6 ṫ 9 = ṫ 8 t 10 = t 6 t 9 ṫ 10 = ṫ 6 t 9 + t 6 ṫ 9 ẋ = 1, ẏ = 0, ṫ 10 = f x and ẋ = 0, ẏ = 1, ṫ 10 = f y tapenade -d -vars "x y" -outvars f costfunc.f Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 26 / 58
Automatic Differentiation: Direct mode SUBROUTINE COSTFUNC_D(x, xd, y, yd, f, fd) t1d = xd t1 = x t2d = yd t2 = y t3d = t1d*t2 + t1*t2d t3 = t1*t2 t4d = t1d*cos(t1) t4 = SIN(t1) t5d = t3d + t4d t5 = t3 + t4 t6d = t5d t6 = t5 + 4 t7d = 2*t2*t2d t7 = t2**2 t8d = 3.0*t7d t8 = 3.0*t7 t9d = t8d t9 = t8 + 6.0 t10d = t6d*t9 + t6*t9d t10 = t6*t9 fd = t10d f = t10 END Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 27 / 58
Backward differentiation Program P is a sequence of computations F k T 0 = X, given k th line t k = F k (T k 1 ), T k = Function is a composition [ Tk 1 F = F p F p 1... F 2 F 1 Chain rule X = [F (X)] Ȳ = [F 1(T 0 )] [F 2(T 1 )]... [F p 1(T p 2 )] [F p(t p 1 )] Ȳ X, Ȳ X cost( X) = 4 cost(y ) t k ] Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 28 / 58
Differentiation: Reverse mode Apply chain rule of differentiation in reverse t 1 = x t 10 = 1 t 2 = y t 9 = t 10 t 10,9 = t 6 t 3 = t 1 t 2 t 8 = t 9 t 9,8 = t 6 t 4 = sin(t 1 ) t 7 = t 8 t 8,7 = 3t 6 t 5 = t 3 + t 4 t 6 = t 10 t 10,6 = t 9 t 6 = t 5 + 4 t 5 = t 6 t 6,5 = t 9 t 7 = t 2 2 t 4 = t 5 t 5,4 = t 9 t 8 = 3t 7 t 3 = t 5 t 5,3 = t 9 t 9 = t 8 + 6 t 2 = t 7 t 7,2 + t 3 t 3,2 = 6t 2 t 6 + t 1 t 9 t 10 = t 6 t 9 t 1 = t 4 t 4,1 + t 3 t 3,1 = t 9 cos(t 1 ) + t 9 t 2 t 1 = f x, t 2 = f y tapenade -b -vars "x y" -outvars f costfunc.f Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 29 / 58
Automatic Differentiation: Reverse mode SUBROUTINE COSTFUNC_B(x, xb, y, yb, f, fb) t1 = x t2 = y t3 = t1*t2 t4 = SIN(t1) t5 = t3 + t4 t6 = t5 + 4 t7 = t2**2 t8 = 3.0*t7 t9 = t8 + 6.0 t10b = fb t6b = t9*t10b t9b = t6*t10b t8b = t9b t7b = 3.0*t8b t5b = t6b t3b = t5b t2b = t1*t3b + 2*t2*t7b t4b = t5b t1b = t2*t3b + COS(t1)*t4b yb = t2b xb = t1b fb = 0.0 END Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 30 / 58
Direct versus reverse AD F : R m R n Direct mode Reverse mode cost(j) = m 4 cost(p ) cost(j) = n 4 cost(p ) Scalar output F R, n = 1 Direct mode gives F Ẋ for given vector Ẋ Reverse mode gives F, hence preferred Vector output F R n Direct mode gives F Ẋ for given vector Ẋ use for sensitivity equation approach Reverse mode gives ( F ) Ȳ use for adjoint approach Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 31 / 58
Black-box AD cost depends on alpha call ComputeCost(alpha, cost) Subroutine for cost function subroutine ComputeCost(alpha, cost) call SolveState(alpha, u) call CostFun(alpha, u, cost) end Reverse differentiation using AD tapenade -backward \ -head ComputeCost \ -vars alpha \ -outvars cost \ ComputeCost.f SolveState.f CostFun.f Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 32 / 58
Black-box AD Diffentiated subroutines: ComputeCost b.f, SolveState b.f, CostFun b.f subroutine ComputeCost_b(alpha,alphab,cost,costb) call SolveState(alpha, u) call CostFun_b(alpha, alphab, u, ub, cost, costb) call SolveState_b(alpha, alphab, u, ub) end Compute gradient using costb = 1.0 call ComputeCost_b(alpha, alphab, cost, costb) Gradient given by alphab alphab = (cost) (alpha) Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 33 / 58
AD for iterative problems Solve state equation R(α, u) = 0 as steady state of du dt + R(α, u) = 0, u(0) = u o State solver subroutine SolveState(alpha, u) u = 0.0 do call Residue(alpha, u, res) u = u - dt * res while( abs(res) > TOL) end subroutine Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 34 / 58
AD for iterative problems Adjoint solver, hand written subroutine SolveState_b(alpha,alphab,u,ub) resb = 0.0 do ub1 = 0.0 call Residue_bu(alpha,u,ub1,res,resb) resb = resb - (ub + ub1) while( abs(ub+ub1).gt. 1.0e-5) call Residue_ba(alpha,alphab,u,res,resb) end subroutine resb = Adjoint variable ub = J u, ub1 = [ ] R v u Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 35 / 58
Adjoint iterative scheme Forward iterations linearly stable Adjoint iteration u n+1 = u n t R(α, u n ), t < S(σ(R )) v n+1 = v n t { [R (α, u )] v n + J } u [R ] has same eigenvalues as R = adjoint iterations stable under same condition on t Preconditioner for adjoint = (preconditioner for primal problem) Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 36 / 58
AD tools Source transformation (ST) and operator overloading (OO) See http://www.autodiff.org Tool Modes Method Lang ADIFOR F ST Fortran ADOLC F/B OO C TAPENADE F/B ST Fortran/C TAF/TAMC F/B ST Fortran/C MAD F OO Matlab Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 37 / 58
Quasi 1-D flow Inflow x h(x) Outflow Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 38 / 58
Quasi 1-D flow Quasi 1-D flow in a duct t (hu) + dh (hf) = P, x dx x (a, b) t > 0 ρ ρu 0 U = ρu, f = p + ρu 2, P = p E (E + p)u 0 h(x) = cross-section height of duct Inverse design: find shape h to get pressure distribution p Optimization problem: find the shape h which minimizes J = b a (p p ) 2 dx Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 39 / 58
Quasi 1-D flow Inflow face 1 i N i 1/2 i + 1/2 Outflow face Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 40 / 58
Quasi 1-D flow Finite volume scheme for cell C i = [x i 1/2, x i+1/2 ] du i h i dt + h i+1/2f i+1/2 h i 1/2 F i 1/2 x Discrete cost function = (h i+1/2 h i 1/2 ) P i x J = N (p i p i ) 2 i=1 Control variables N = 100 h 1/2, h 1+1/2,..., h i+1/2,..., h N+1/2 Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 41 / 58
Duct shape 1.9 1.8 1.7 Duct shape Target shape Current shape 1.6 h 1.5 1.4 1.3 1.2 1.1 1 0 2 4 6 8 10 x Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 42 / 58
Target pressure distribution p 2.5 2 Target pressure AUSMDV KFVS LF Pressure 1.5 1 0.5 0 2 4 6 8 10 x Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 43 / 58
Current pressure distribution 2.5 2 Starting pressure AUSMDV KFVS LF Pressure 1.5 1 0.5 0 2 4 6 8 10 x Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 44 / 58
Adjoint density 5 0 AUSMDV KFVS LF 5 Adjoint density 10 15 20 25 30 35 0 2 4 6 8 10 x Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 45 / 58
Convergence history: Explicit Euler Residue 0 1 2 3 4 5 6 7 8 9 Convergence history with AUSMDV flux Flow Adjoint 10 1000 2000 3000 4000 5000 6000 7000 No of iterations Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 46 / 58
Shape gradient 35 30 Gradient AUSMDV KFVS LF 25 Gradient 20 15 10 5 0 0 2 4 6 8 10 x Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 47 / 58
Shape gradient Gradient 40 35 30 25 20 15 10 Gradient AUSMDV KFVS LF 5 0 5 2 2.5 3 3.5 4 4.5 5 5.5 6 x Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 48 / 58
Validation of Shape gradient 35 Gradient with AUSMDV flux 30 25 B Gradient 20 15 10 5 A C 0 0 2 4 6 8 10 x Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 49 / 58
Validation of shape gradient J h J(h + h) J(h h) 2 h h A B C 0.01 0.4191069499 35.18452823 2.545316345 0.001 0.4231223499 36.10982621 2.556461900 0.0001 0.4231624999 36.11933154 2.556573499 0.00001 0.4231599998 36.11942125 2.556575000 0.000001 0.4231999994 36.11942305 2.556550001 0.0000001 0.4229999817 36.11942329 2.556499971 AD 0.4231628330 36.11941951 2.556574450 Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 50 / 58
Gradient smoothing Non-smooth gradients G especially in the presence of shocks Smooth using an elliptic equation ) (1 ɛ(x) d2 dx 2 Ḡ(x) = G(x) L i = ɛ i = { G i+1 G i + G i G i 1 }L i G i+1 2G i + G i 1 max( G i+1 G i + G i G i 1, TOL) Finite difference with Jacobi iterations Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 51 / 58
Gradient smoothing 35 30 Gradient using AUSMDV flux Original gradient Smoothed gradient 25 Gradient 20 15 10 5 0 0 2 4 6 8 10 x Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 52 / 58
Quasi 1-D optimization: Shape 1.9 1.8 Target Initial 1.7 1.6 1.5 h 1.4 1.3 1.2 1.1 1 0 1 2 3 4 5 6 7 8 9 10 x Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 53 / 58
Quasi 1-D optimization: Final shape 1.9 1.8 1.7 1.6 1.5 h 1.4 1.3 Target Initial Final 1.2 1.1 1 0 1 2 3 4 5 6 7 8 9 10 x Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 54 / 58
Quasi 1-D optimization: Pressure 2.5 2 Pressure 1.5 Target Initial Final 1 0.5 0 1 2 3 4 5 6 7 8 9 10 x Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 55 / 58
Quasi 1-D optimization: Convergence 10 0 Cost Gradient 10 1 10 2 Cost/Gradient 10 3 10 4 10 5 10 6 0 5 10 15 20 25 30 35 40 45 50 No. of iterations Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 56 / 58
Quasi 1-D optimization: Adjoint density 0 5 Adjoint density 10 15 Initial Final 20 25 0 2 4 6 8 10 x Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 57 / 58
Example codes 1-D example: nozzle flow (TAPENADE) http://cfdlab.googlecode.com 1-D example: nozzle flow (ADOLC) http://cfdlab.googlecode.com 2-D example: unstructured grid Euler solver (TAPENADE) http://euler2d.sourceforge.net 2/3-D example: structured grid Euler solver (TAPENADE) http://nuwtun.berlios.de Praveen. C (TIFR-CAM) Optimization BARC, 6 Oct 2010 58 / 58