algebramix_doc 0.3
|
00001 00002 /****************************************************************************** 00003 * MODULE : series.hpp 00004 * DESCRIPTION: Univariate power series 00005 * COPYRIGHT : (C) 2004 Joris van der Hoeven 00006 ******************************************************************************* 00007 * This software falls under the GNU general public license and comes WITHOUT 00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details. 00009 * If you don't have this file, write to the Free Software Foundation, Inc., 00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00011 ******************************************************************************/ 00012 00013 #ifndef __MMX_SERIES_NAIVE__HPP 00014 #define __MMX_SERIES_NAIVE__HPP 00015 #include <algebramix/polynomial.hpp> 00016 00017 namespace mmx { 00018 #define TMPL template<typename C, typename V> 00019 #define Format format<C> 00020 #define Series series<C,V> 00021 #define Series_rep series_rep<C,V> 00022 #define Recursive_series_rep recursive_series_rep<C,V> 00023 #define Polynomial polynomial<C, typename series_polynomial_helper<C,V>::PV> 00024 00025 template<typename C> 00026 struct series_variant_helper; 00027 00028 template <typename C, typename V=typename series_variant_helper<C>::SV> 00029 class series_rep; 00030 00031 template <typename C, typename V=typename series_variant_helper<C>::SV> 00032 class series; 00033 00034 template <typename C, typename V=typename series_variant_helper<C>::SV> 00035 class recursive_series_rep; 00036 00037 /****************************************************************************** 00038 * Naive variant for series 00039 ******************************************************************************/ 00040 00041 struct series_naive {}; 00042 00043 template<typename C> 00044 struct series_variant_helper { 00045 typedef series_naive SV; 00046 }; 00047 00048 template<typename C, typename V> 00049 struct series_polynomial_helper { 00050 typedef typename Polynomial_variant(C) PV; 00051 }; 00052 00053 /****************************************************************************** 00054 * Global variables, default is R[z] 00055 ******************************************************************************/ 00056 00057 struct series_defaults {}; 00058 00059 template<typename V> 00060 struct implementation<series_defaults,V,series_naive> { 00061 00062 template<typename S> 00063 class global_variables { 00064 00065 static inline generic& dyn_name () { 00066 static generic name = "z"; 00067 return name; } 00068 00069 static inline nat& dyn_output_order () { 00070 static nat n = 10; 00071 return n; } 00072 00073 static inline nat& dyn_cancel_order () { 00074 static nat n = 5; 00075 return n; } 00076 00077 static inline bool& dyn_formula_output () { 00078 static bool b = false; 00079 return b; } 00080 00081 public: 00082 static inline void set_variable_name (const generic& x) { 00083 dyn_name () = x; } 00084 static inline generic get_variable_name () { 00085 return dyn_name (); } 00086 static inline void set_output_order (const nat& x) { 00087 dyn_output_order () = x; } 00088 static inline nat get_output_order () { 00089 return dyn_output_order (); } 00090 static inline void set_cancel_order (const nat& x) { 00091 dyn_cancel_order () = x; } 00092 static inline nat get_cancel_order () { 00093 return dyn_cancel_order (); } 00094 static inline void set_formula_output (const bool& x) { 00095 dyn_formula_output () = x; } 00096 static inline bool get_formula_output () { 00097 return dyn_formula_output (); } 00098 }; 00099 }; // implementation<series_defaults,V,series_naive> 00100 00101 /****************************************************************************** 00102 * Abstract scalar operations on series 00103 ******************************************************************************/ 00104 00105 struct series_scalar_abstractions {}; 00106 00107 template<typename U> 00108 struct implementation<series_scalar_abstractions,U,series_naive>: 00109 public implementation<series_defaults,U> 00110 { 00111 00112 template<typename Op,typename C,typename V,typename X> 00113 class binary_scalar_series_rep: public Series_rep { 00114 protected: 00115 Series f; 00116 X x; 00117 public: 00118 inline binary_scalar_series_rep (const Series& f2, const X& x2): 00119 Series_rep (CF(f2)), f(f2), x (x2) {} 00120 syntactic expression (const syntactic& z) const { 00121 return Op::op (flatten (f, z), flatten (x)); } 00122 virtual void Increase_order (nat l) { 00123 Series_rep::Increase_order (l); 00124 increase_order (f, l); } 00125 virtual C next () { return Op::op (f[this->n], x); } 00126 }; 00127 00128 template<typename Op,typename C,typename V,typename X,typename Y> 00129 class ternary_scalar_series_rep: public Series_rep { 00130 protected: 00131 Series f; 00132 X x; 00133 Y y; 00134 public: 00135 inline ternary_scalar_series_rep (const Series& f2, const X& a, const Y& b): 00136 Series_rep (CF(f2)), f (f2), x (a), y (b) {} 00137 syntactic expression (const syntactic& z) const { 00138 return Op::op (flatten (f, z), flatten (x), flatten (y)); } 00139 virtual void Increase_order (nat l) { 00140 Series_rep::Increase_order (l); 00141 increase_order (f, l); } 00142 virtual C next () { return Op::op (f[this->n], x, y); } 00143 }; 00144 }; // implementation<series_abstractions,V,series_naive> 00145 00146 /****************************************************************************** 00147 * Abstract maps on series 00148 ******************************************************************************/ 00149 00150 struct series_map_as_abstractions {}; 00151 00152 template<typename U> 00153 struct implementation<series_map_as_abstractions,U,series_naive>: 00154 public implementation<series_scalar_abstractions,U> 00155 { 00156 00157 template<typename Op, typename C, typename V, typename S, typename SV> 00158 class unary_map_as_series_rep: public Series_rep { 00159 protected: 00160 series<S,SV> f; 00161 public: 00162 inline unary_map_as_series_rep (const series<S,SV>& f2, const Format& fm): 00163 Series_rep (fm), f (f2) {} 00164 inline unary_map_as_series_rep (const series<S,SV>& f2): 00165 Series_rep (unary_map<Op> (CF(f2))), f (f2) {} 00166 syntactic expression (const syntactic& z) const { 00167 return Op::op (flatten (f, z)); } 00168 virtual void Increase_order (nat l) { 00169 Series_rep::Increase_order (l); 00170 increase_order (f, l); } 00171 virtual C next () { 00172 C r= get_sample (this->tfm ()); 00173 Op::set_op (r, f[this->n]); 00174 return r; } 00175 }; 00176 00177 template<typename Op, typename C, typename V, typename S, typename SV> 00178 static inline Series 00179 unary_map_as (const series<S,SV>& f, const Format& fm) { 00180 typedef unary_map_as_series_rep<Op,C,V,S,SV> Unary; 00181 return (Series_rep*) new Unary (f, fm); 00182 } 00183 00184 template<typename Op, typename C, typename V, typename S, typename SV> 00185 static inline Series 00186 unary_map_as (const series<S,SV>& f) { 00187 return unary_map_as<Op,C,V,S,SV> (f, unary_map<Op> (CF(f))); 00188 } 00189 00190 }; // implementation<series_map_as_abstractions,V,series_naive> 00191 00192 /****************************************************************************** 00193 * Abstract recursive operations on series 00194 ******************************************************************************/ 00195 00196 struct series_recursive_abstractions {}; 00197 00198 template<typename U> 00199 struct implementation<series_recursive_abstractions,U,series_naive>: 00200 public implementation<series_map_as_abstractions,U> 00201 { 00202 00203 template<typename Op,typename C, 00204 typename V=typename series_variant_helper<C>::SV> 00205 class nullary_recursive_series_rep: public Recursive_series_rep { 00206 protected: 00207 C c; 00208 public: 00209 nullary_recursive_series_rep (const C& c2): 00210 Recursive_series_rep (get_format (c)), c (c2) {} 00211 syntactic expression (const syntactic& z) const { 00212 (void) z; 00213 return Op::op_init (flatten (c)); } 00214 Series initialize () { 00215 this->initial (0)= c; 00216 return Op::def (Series (this->me ())); } 00217 }; 00218 00219 template<typename Op,typename C,typename V> 00220 class unary_recursive_series_rep: public Recursive_series_rep { 00221 protected: 00222 Series f; 00223 bool with_init; 00224 C c; 00225 public: 00226 unary_recursive_series_rep (const Series& f2): 00227 Recursive_series_rep (CF(f2)), f (f2), with_init (false) {} 00228 unary_recursive_series_rep (const Series& f2, const C& c2): 00229 Recursive_series_rep (CF(f2)), f (f2), with_init (true), c (c2) {} 00230 syntactic expression (const syntactic& z) const { 00231 return Op::op (flatten (f, z)); } 00232 virtual void Increase_order (nat l) { 00233 Recursive_series_rep::Increase_order (l); 00234 increase_order (f, l); } 00235 Series initialize () { 00236 if (with_init) this->initial (0)= c; 00237 else { 00238 ASSERT (Op::nr_init () <= 1, "wrong number of initial conditions"); 00239 if (Op::nr_init () == 1) 00240 this->initial (0)= Op::op (f[0]); 00241 } 00242 return Op::def (Series (this->me ()), f); } 00243 }; 00244 00245 template<typename Op,typename C,typename V> 00246 class binary_recursive_series_rep: public Recursive_series_rep { 00247 protected: 00248 Series f, g; 00249 public: 00250 binary_recursive_series_rep (const Series& f2, const Series& g2): 00251 Recursive_series_rep (CF(f2)), f(f2), g(g2) {} 00252 syntactic expression (const syntactic& z) const { 00253 return Op::op (flatten (f, z), flatten (g, z)); } 00254 virtual void Increase_order (nat l) { 00255 Recursive_series_rep::Increase_order (l); 00256 increase_order (f, l); 00257 increase_order (g, l); } 00258 Series initialize () { 00259 ASSERT (Op::nr_init () <= 1, "wrong number of initial conditions"); 00260 if (Op::nr_init () == 1) this->initial (0)= Op::op (f[0], g[0]); 00261 return Op::def (Series (this->me ()), f, g); 00262 } 00263 }; 00264 00265 template<typename Op,typename C,typename V,typename X> 00266 class binary_scalar_recursive_series_rep: public Recursive_series_rep { 00267 protected: 00268 Series f; 00269 bool with_init; 00270 X x; 00271 C c; 00272 00273 public: 00274 binary_scalar_recursive_series_rep (const Series& f2, const X& x2): 00275 Recursive_series_rep (CF(f2)), f (f2), with_init (false), x (x2) {} 00276 binary_scalar_recursive_series_rep (const Series& f2, const X& x2, 00277 const C& c2): 00278 Recursive_series_rep (CF(f2)), f (f2), with_init (true), x (x2), c (c2) {} 00279 syntactic expression (const syntactic& z) const { 00280 return Op::op (flatten (f, z), flatten (x)); } 00281 virtual void Increase_order (nat l) { 00282 Recursive_series_rep::Increase_order (l); 00283 increase_order (f, l); } 00284 Series initialize () { 00285 if (with_init) this->initial (0)= c; 00286 else { 00287 ASSERT (Op::nr_init () <= 1, "wrong number of initial conditions"); 00288 if (Op::nr_init () == 1) 00289 this->initial (0)= Op::op (f[0], x); 00290 } 00291 return Op::def (Series (this->me ()), f, x); } 00292 }; 00293 00294 }; // implementation<series_recursive_abstractions,V,series_naive> 00295 00296 /****************************************************************************** 00297 * Abstract operations on series 00298 ******************************************************************************/ 00299 00300 struct series_abstractions {}; 00301 00302 template<typename U> 00303 struct implementation<series_abstractions,U,series_naive>: 00304 public implementation<series_recursive_abstractions,U> 00305 { 00306 00307 template<typename Op,typename C,typename V> 00308 class unary_series_rep: public Series_rep { 00309 protected: 00310 Series f; 00311 public: 00312 inline unary_series_rep (const Series& f2): 00313 Series_rep (CF(f2)), f(f2) {} 00314 syntactic expression (const syntactic& z) const { 00315 return Op::op (flatten (f, z)); } 00316 virtual void Increase_order (nat l) { 00317 Series_rep::Increase_order (l); 00318 increase_order (f, l); } 00319 virtual C next () { return Op::op (f[this->n]); } 00320 }; 00321 00322 template<typename Op,typename C,typename V> 00323 class binary_series_rep: public Series_rep { 00324 protected: 00325 Series f, g; 00326 public: 00327 inline binary_series_rep (const Series& f2, const Series& g2): 00328 Series_rep (CF(f2)), f(f2), g (g2) {} 00329 syntactic expression (const syntactic& z) const { 00330 return Op::op (flatten (f, z), flatten (g, z)); } 00331 virtual void Increase_order (nat l) { 00332 Series_rep::Increase_order (l); 00333 increase_order (f, l); 00334 increase_order (g, l); } 00335 virtual C next () { return Op::op (f[this->n], g[this->n]); } 00336 }; 00337 00338 }; // implementation<series_abstractions,V,series_naive> 00339 00340 /****************************************************************************** 00341 * Multiplication 00342 ******************************************************************************/ 00343 00344 struct series_multiply {}; 00345 00346 template<typename U> 00347 struct implementation<series_multiply,U,series_naive>: 00348 public implementation<series_abstractions,U> 00349 { 00350 typedef implementation<series_abstractions,U> Ser; 00351 TMPL 00352 class mul_series_rep: public Ser::template binary_series_rep<mul_op,C,V> { 00353 public: 00354 inline mul_series_rep (const Series& f, const Series& g): 00355 Ser::template binary_series_rep<mul_op,C,V> (f, g) {} 00356 C next () { 00357 nat i; 00358 C acc= this->f[0] * this->g[this->n]; 00359 for (i=1; i<=this->n; i++) 00360 acc += this->f[i] * this->g[this->n-i]; 00361 return acc; } 00362 }; 00363 00364 TMPL 00365 class truncate_mul_series_rep: 00366 public Ser::template binary_series_rep<mul_op,C,V> { 00367 nat nf, ng; 00368 public: 00369 inline truncate_mul_series_rep (const Series& f, const Series& g, 00370 nat nf2, nat ng2): 00371 Ser::template binary_series_rep<mul_op,C,V> (f, g), nf (nf2), ng (ng2) {} 00372 C next () { 00373 nat i, n= this->n; 00374 C acc= this->zero (); 00375 for (i= n >= ng ? n - ng + 1 : 0; i < min (1 + n, nf); i++) 00376 acc += this->f[i] * this->g[n-i]; 00377 return acc; } 00378 }; 00379 00380 TMPL static inline Series 00381 ser_mul (const Series& f, const Series& g) { 00382 typedef mul_series_rep<C,V> Mul_rep; 00383 if (is_exact_zero (f) || is_exact_zero (g)) 00384 return Series (CF(f)); 00385 return (Series_rep*) new Mul_rep (f, g); } 00386 00387 TMPL static inline Series 00388 ser_truncate_mul (const Series& f, const Series& g, nat nf, nat ng) { 00389 typedef truncate_mul_series_rep<C,V> Mul_rep; 00390 if (is_exact_zero (f) || is_exact_zero (g) || nf == 0 || ng == 0) 00391 return Series (CF(f)); 00392 return (Series_rep*) new Mul_rep (f, g, nf, ng); } 00393 00394 }; // implementation<series_multiply,V,series_naive> 00395 00396 /****************************************************************************** 00397 * Division 00398 ******************************************************************************/ 00399 00400 struct series_divide {}; 00401 00402 template<typename U> 00403 struct implementation<series_divide,U,series_naive>: 00404 public implementation<series_multiply,U> 00405 { 00406 00407 TMPL static inline Series 00408 ser_rdiv_sc (const Series& f, const C& c) { 00409 typedef implementation<series_scalar_abstractions,U> Ser; 00410 typedef typename Ser:: 00411 template binary_scalar_series_rep<rdiv_op,C,V,C> Div_sc_rep; 00412 if (is_exact_zero (f)) return Series (CF(f)); 00413 return (Series_rep*) new Div_sc_rep (f, c); } 00414 00415 TMPL static inline Series 00416 ser_div (const Series& f, const Series& g) { 00417 typedef implementation<series_recursive_abstractions,U> Ser; 00418 typedef typename Ser:: 00419 template binary_recursive_series_rep<div_op,C,V> Div_rep; 00420 if (is_exact_zero (f)) return Series (CF(f)); 00421 return recursive (Series ((Series_rep*) new Div_rep (f, g))); } 00422 00423 TMPL static inline Series 00424 ser_rquo_sc (const Series& f, const C& c) { 00425 typedef implementation<series_scalar_abstractions,U> Ser; 00426 typedef typename Ser 00427 ::template binary_scalar_series_rep<rquo_op,C,V,C> Rquo_rep; 00428 if (is_exact_zero (f)) return Series (CF(f)); 00429 return (Series_rep*) new Rquo_rep (f, c); } 00430 00431 TMPL static inline Series 00432 ser_quo (const Series& f, const Series& g) { 00433 typedef implementation<series_recursive_abstractions,U> Ser; 00434 typedef typename Ser 00435 ::template binary_recursive_series_rep<quo_op,C,V> Quo_rep; 00436 if (is_exact_zero (f)) return Series (CF(f)); 00437 return recursive (Series ((Series_rep*) new Quo_rep (f, g))); } 00438 00439 TMPL static inline Series 00440 ser_rrem_sc (const Series& f, const C& c) { 00441 typedef implementation<series_scalar_abstractions,U> Ser; 00442 typedef typename Ser 00443 ::template binary_scalar_series_rep<rrem_op,C,V> Rrem_rep; 00444 if (is_exact_zero (f)) return Series (CF(f)); 00445 return (Series_rep*) new Rrem_rep (f, c); } 00446 00447 }; // implementation<series_divide,V,series_naive> 00448 00449 /****************************************************************************** 00450 * Composition and reversion 00451 ******************************************************************************/ 00452 00453 struct series_compose {}; 00454 00455 template<typename U> 00456 struct implementation<series_compose,U,series_naive>: 00457 public implementation<series_multiply,U> 00458 { 00459 00460 TMPL 00461 class compose_series_rep: public Series_rep { 00462 Series f; 00463 Series g; 00464 Series cumul; 00465 Series power; 00466 public: 00467 inline compose_series_rep (const Series& f2, const Series& g2): 00468 Series_rep (CF(f2)), f (f2), g (g2), 00469 cumul (CF(f2)), power (promote (1, CF(f2))) {} 00470 syntactic expression (const syntactic& z) const { 00471 return apply (GEN_COMPOSE, flatten (f, z), flatten (g, z)); } 00472 void Increase_order (nat l) { 00473 Series_rep::Increase_order (l); 00474 increase_order (f, l); 00475 increase_order (g, l); 00476 increase_order (cumul, l); 00477 increase_order (power, l); } 00478 C next () { 00479 cumul += f[this->n] * power; 00480 power *= g; 00481 return cumul[this->n]; 00482 } 00483 }; 00484 00485 TMPL static inline Series 00486 ser_compose (const Series& f, const Series& g) { 00487 typedef compose_series_rep<C,V> Compose_rep; 00488 if (is_exact_zero (f)) return Series (CF(f)); 00489 ASSERT (g[0] == 0, "constant coefficient must be zero"); 00490 return (Series_rep*) new Compose_rep (f, g); } 00491 00492 TMPL 00493 class reverse_series_rep: public Recursive_series_rep { 00494 protected: 00495 Series f; 00496 public: 00497 reverse_series_rep (const Series& f2): 00498 Recursive_series_rep (CF(f2)), f (f2) {} 00499 syntactic expression (const syntactic& z) const { 00500 return apply (GEN_REVERSE, flatten (f, z)); } 00501 virtual void Increase_order (nat l) { 00502 Recursive_series_rep::Increase_order (l); 00503 increase_order (f, l); } 00504 Series initialize () { 00505 ASSERT (f[0] == 0 && f[1] != 0, "invalid reversion"); 00506 C a= f[1]; 00507 Series z (this->one (), 1); 00508 Series s= square (rshiftz (this->me (), 1)); 00509 Series c= compose (rshiftz (this->f, 2), this->me ()); 00510 return (z - lshiftz (c * s, 2)) / a; } 00511 }; 00512 00513 TMPL static inline Series 00514 ser_reverse (const Series& f) { 00515 typedef reverse_series_rep<C,V> Reverse_rep; 00516 Series_rep* rep= new Reverse_rep (f); 00517 return recursive (Series (rep)); } 00518 00519 }; // implementation<series_compose,V,series_naive> 00520 00521 /****************************************************************************** 00522 * separable_root 00523 ******************************************************************************/ 00524 00525 struct ser_separable_root_op { 00526 // regular case when r is invertible in the residual field 00527 00528 private: 00529 template<typename S> static S 00530 binpow_no_tangent (const S& me, nat r) { 00531 typedef Scalar_type(S) C; 00532 // me^r - r * (me - me[0]) * me[0]^(r-1) - me[0]^r 00533 if (r <= 1) return S (0); 00534 if (r == 2) return lshiftz (square (rshiftz (me, 1)), 2); 00535 00536 nat h= r >> 1; 00537 C x= me[0]; 00538 C x_h_1= binpow (x, h-1); 00539 S y= me - me[0]; 00540 S z= rshiftz (binpow_no_tangent (me, h), 1); 00541 S t0= as<C> (h) * y; 00542 S t1= square (rshiftz (t0 * x_h_1, 1)); 00543 S t2= x_h_1 * z * (t0 + x); 00544 S w= lshiftz (square (z) + t1, 2) + lshiftz (t2 + t2, 1); 00545 if (r & 1) { 00546 nat h2= h << 1; 00547 w= rshiftz (w, 1); 00548 w= lshiftz ((y + x) * w, 1) 00549 + lshiftz (as<C> (h2) * square (rshiftz (y * x_h_1, 1)) * x, 2); 00550 } 00551 return w; } 00552 00553 public: 00554 static generic name () { return "separable_root"; } 00555 00556 template<typename S> static inline S 00557 op (const S& x, nat r) { return separable_root (x, r); } 00558 00559 static inline syntactic 00560 op (const syntactic& x, const syntactic& r) { 00561 return apply ("separable_root", x, r); } 00562 00563 template<typename R, typename S> static inline void 00564 set_op (R& x, const S& y, nat r) { x= separable_root (y, r); } 00565 00566 template<typename S, typename I> static inline S 00567 op_init (const S& x, nat r, const I& i) { 00568 return separable_root_init (x, r, i); } 00569 00570 static inline nat nr_init () { return 1; } 00571 00572 template<typename S> static inline S 00573 def (const S& me, const S& a, nat r) { 00574 typedef Scalar_type(S) C; 00575 C me0_r_1= binpow (me[0], r - 1); 00576 C me0_r= me[0] * me0_r_1; 00577 return (a - me0_r - binpow_no_tangent (me, r)) / (as<C> (r) * me0_r_1); } 00578 00579 }; // struct ser_separable_root_op 00580 00581 struct series_separable_root {}; 00582 00583 template<typename U> 00584 struct implementation<series_separable_root,U,series_naive> { 00585 00586 TMPL static inline Series 00587 sep_root (const Series& a, nat r) { 00588 typedef implementation<series_recursive_abstractions,U> Ser; 00589 typedef typename Ser::template binary_scalar_recursive_series_rep 00590 <ser_separable_root_op,C,V,nat> Root; 00591 ASSERT (C(r) != 0, "wrong argument"); 00592 if (is_exact_zero (a)) return Series (CF(a)); 00593 Series_rep* rep= new Root (a, r); 00594 return recursive (Series (rep)); } 00595 00596 TMPL static inline Series 00597 sep_root (const Series& a, nat r, const C& init) { 00598 typedef implementation<series_recursive_abstractions,U> Ser; 00599 typedef typename Ser::template binary_scalar_recursive_series_rep 00600 <ser_separable_root_op,C,V,nat> Root; 00601 ASSERT (C(r) != 0, "wrong argument"); 00602 if (is_exact_zero (a)) return Series (CF(a)); 00603 Series_rep* rep= new Root (a, r); 00604 return recursive (Series (rep)); } 00605 00606 }; // implementation<series_separable_root,V,series_naive> 00607 00608 /****************************************************************************** 00609 * pth root where p is the characteristic 00610 ******************************************************************************/ 00611 00612 struct series_pth_root_reg {}; 00613 struct series_pth_root {}; 00614 00615 template<typename U> 00616 struct implementation<series_pth_root,U,series_naive> { 00617 00618 TMPL static inline Series 00619 unsep_root (const Series& f) { ERROR ("not implemented"); } 00620 00621 }; // implementation<series_unseparable_root,V,series_naive> 00622 00623 #undef TMPL 00624 #undef Format 00625 #undef Series 00626 #undef Series_rep 00627 #undef Recursive_series_rep 00628 #undef Polynomial 00629 } // namespace mmx 00630 #endif // __MMX_SERIES_NAIVE__HPP