| 1 |  |  | """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | Class for approximating the solution to two-point boundary value problems using | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | either standard or orthogonal polynomials as basis functions. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | @author: davidrpugh | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | import numpy as np | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | from . import basis_functions | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |  | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 12 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 13 |  |  | class PolynomialBasis(basis_functions.BasisFunctionLike): | 
            
                                                        
            
                                    
            
            
                | 14 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 15 |  |  |     _valid_kinds = ['Polynomial', 'Chebyshev', 'Legendre', 'Laguerre', 'Hermite'] | 
            
                                                        
            
                                    
            
            
                | 16 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 17 |  |  |     @staticmethod | 
            
                                                        
            
                                    
            
            
                | 18 |  |  |     def _basis_monomial_coefs(degree): | 
            
                                                        
            
                                    
            
            
                | 19 |  |  |         """Return coefficients for a monomial of a given degree.""" | 
            
                                                        
            
                                    
            
            
                | 20 |  |  |         return np.append(np.zeros(degree), 1) | 
            
                                                        
            
                                    
            
            
                | 21 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 22 |  |  |     @classmethod | 
            
                                                        
            
                                    
            
            
                | 23 |  |  |     def _basis_polynomial_factory(cls, kind): | 
            
                                                        
            
                                    
            
            
                | 24 |  |  |         """Return a polynomial given some coefficients.""" | 
            
                                                        
            
                                    
            
            
                | 25 |  |  |         valid_kind = cls._validate(kind) | 
            
                                                        
            
                                    
            
            
                | 26 |  |  |         basis_polynomial = getattr(np.polynomial, valid_kind) | 
            
                                                        
            
                                    
            
            
                | 27 |  |  |         return basis_polynomial | 
            
                                                        
            
                                    
            
            
                | 28 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 29 |  |  |     @classmethod | 
            
                                                        
            
                                    
            
            
                | 30 |  |  |     def _validate(cls, kind): | 
            
                                                        
            
                                    
            
            
                | 31 |  |  |         """Validate the kind argument.""" | 
            
                                                        
            
                                    
            
            
                | 32 |  |  |         if kind not in cls._valid_kinds: | 
            
                                                        
            
                                    
            
            
                | 33 |  |  |             mesg = "'kind' must be one of {}, {}, {}, or {}." | 
            
                                                        
            
                                    
            
            
                | 34 |  |  |             raise ValueError(mesg.format(*cls._valid_kinds)) | 
            
                                                        
            
                                    
            
            
                | 35 |  |  |         else: | 
            
                                                        
            
                                    
            
            
                | 36 |  |  |             return kind | 
            
                                                        
            
                                    
            
            
                | 37 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 38 |  |  |     @classmethod | 
            
                                                        
            
                                    
            
            
                | 39 |  |  |     def derivatives_factory(cls, coef, domain, kind, **kwargs): | 
            
                                                        
            
                                    
            
            
                | 40 |  |  |         """ | 
            
                                                        
            
                                    
            
            
                | 41 |  |  |         Given some coefficients, return a the derivative of a certain kind of | 
            
                                                        
            
                                    
            
            
                | 42 |  |  |         orthogonal polynomial defined over a specific domain. | 
            
                                                        
            
                                    
            
            
                | 43 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 44 |  |  |         """ | 
            
                                                        
            
                                    
            
            
                | 45 |  |  |         basis_polynomial = cls._basis_polynomial_factory(kind) | 
            
                                                        
            
                                    
            
            
                | 46 |  |  |         return basis_polynomial(coef, domain).deriv() | 
            
                                                        
            
                                    
            
            
                | 47 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 48 |  |  |     @classmethod | 
            
                                                        
            
                                    
            
            
                | 49 |  |  |     def fit(cls, ts, xs, degree, domain, kind): | 
            
                                                        
            
                                    
            
            
                | 50 |  |  |         basis_polynomial = cls._basis_polynomial_factory(kind) | 
            
                                                        
            
                                    
            
            
                | 51 |  |  |         return basis_polynomial.fit(ts, xs, degree, domain) | 
            
                                                        
            
                                    
            
            
                | 52 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 53 |  |  |     @classmethod | 
            
                                                        
            
                                    
            
            
                | 54 |  |  |     def functions_factory(cls, coef, domain, kind, **kwargs): | 
            
                                                        
            
                                    
            
            
                | 55 |  |  |         """ | 
            
                                                        
            
                                    
            
            
                | 56 |  |  |         Given some coefficients, return a certain kind of orthogonal polynomial | 
            
                                                        
            
                                    
            
            
                | 57 |  |  |         defined over a specific domain. | 
            
                                                        
            
                                    
            
            
                | 58 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 59 |  |  |         """ | 
            
                                                        
            
                                    
            
            
                | 60 |  |  |         basis_polynomial = cls._basis_polynomial_factory(kind) | 
            
                                                        
            
                                    
            
            
                | 61 |  |  |         return basis_polynomial(coef, domain) | 
            
                                                        
            
                                    
            
            
                | 62 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 63 |  |  |     @classmethod | 
            
                                                        
            
                                    
            
            
                | 64 |  |  |     def roots(cls, degree, domain, kind): | 
            
                                                        
            
                                    
            
            
                | 65 |  |  |         """Return optimal collocation nodes for some orthogonal polynomial.""" | 
            
                                                        
            
                                    
            
            
                | 66 |  |  |         basis_coefs = cls._basis_monomial_coefs(degree) | 
            
                                                        
            
                                    
            
            
                | 67 |  |  |         basis_poly = cls.functions_factory(basis_coefs, domain, kind) | 
            
                                                        
            
                                    
            
            
                | 68 |  |  |         return basis_poly.roots() | 
            
                                                        
            
                                    
            
            
                | 69 |  |  |  |