Skip to content

Commit a3f850b

Browse files
committed
cleanup in gso doc
1 parent 8b2aaec commit a3f850b

File tree

2 files changed

+84
-105
lines changed

2 files changed

+84
-105
lines changed

docs/conf.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959

6060
numpydoc_show_class_members = False
6161

62+
napoleon_use_admonition_for_examples = True
63+
6264
# -----------------------------------------------------------------------------
6365
# Sphinx AutoAPI
6466
# -----------------------------------------------------------------------------
@@ -139,4 +141,4 @@
139141
'python': ('https://docs.python.org/{.major}'.format(sys.version_info), None),
140142
'matplotlib': ('https://matplotlib.org/', None),
141143
'pandas': ('https://pandas.pydata.org/', None),
142-
}
144+
}

src/pytuq/ftools/gso.py

Lines changed: 81 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -8,55 +8,35 @@
88

99

1010
class GLMAP:
11-
'''General linear map and data class
11+
r'''General linear map and data class
1212
1313
Attributes:
1414
1515
npt (int) : number of data points
16-
x (np.ndarray) : 2d float data array of shape (npt,n), npt points each in R^n
17-
L can be : None (or absent)
18-
: 2d float array of shape (:,npt)
19-
: a callable user-provided function
20-
21-
Builds linear map and data object, presumed to underly a regression problem of the form
22-
y = L(x,f(x;w)), given data {(x_1,y_1)...,(x_npt,y_npt)} where x_i is in R^n, x is in R^{npt x n}, and y_i in R
23-
and where w in R^m is a vector of parameters to be estimated
24-
25-
L needs to be linear in f(), with separate L dependence on x being an arbitrary function, so that,
26-
with u = f(x,w) = sum_k w_k f_k(x), we have y = L(x, sum_k w_k f_k(x) ) = sum_k w_k L(x,f_k(x))
27-
or y = A w
28-
with A in R^{npt x m} where A[i,j] = L(x_i,f_j(x_i))
29-
30-
This class can take specs of different linear maps L on functions f(x): x -> u, with u in R^{npt}
31-
32-
We list here multiple options for illustration.
33-
34-
The specification of the linear map lmap=gso.GLMAP(x,L) can be done with L given as either no spec, a function, or an array
35-
if L is None or not specified, then an identiy map is implied, and lmap.eval(f) returns L(x,u) = u
36-
if L is a user-defined array L, i.e. L(x,u):=Lu, (L shape needs to be (:,npt)) then lmap.eval(f) returns Lu
37-
if L is a user-defined callable L (function), then lmap.eval(f) returns L(x,u) as spcified by the user
38-
39-
Thus, the following are all equivalent specs of the None option for L
40-
lmap = gso.GLMAP(x)
41-
lmap = gso.GLMAP(x, np.eye(npt))
42-
lmap = gso.GLMAP(x, lambda x, u: u)
43-
44-
On the other hand, if want a linear matrix map, say L = B (shape (m,npt) ), then can use either of
45-
lmap = gso.GLMAP(x, B)
46-
lmap = gso.GLMAP(x, lambda x, u: B@u)
47-
48-
Alternately, if want a map, e.g.: L(x,f(x)) = exp(x) + x**3 * f(x), one can use e.g.
49-
lmap = gso.GLMAP(x, lambda x, u: np.exp(x) + x**3 * u)
50-
16+
x (np.ndarray) : 2d float data array of shape :math:`(npt,n)`, i.e. :math:`npt` points each in :math:`R^n`.
17+
L (np.ndarray or callable or None) : 2d float array of shape :math:`(M,npt)` or a callable user-provided function or None
18+
19+
Notes:
20+
Builds linear map and data object, presumed to underly a regression problem of the form
21+
:math:`y = L(x,f(x;w))`, given data :math:`\{(x_1,y_1),...,(x_{npt},y_{npt})\}` where :math:`x_i \in R^n`, :math:`x \in R^{npt \times n}`, and :math:`y_i\in R`.
22+
and where :math:`w \in R^m` is a vector of parameters to be estimated.
23+
24+
L needs to be linear in :math:`f()`, with separate L dependence on :math:`x` being an arbitrary function, so that, with :math:`u = f(x,w) = \sum_k w_k f_k(x)`, we have :math:`y = L(x, \sum_k w_k f_k(x) ) = \sum_k w_k L(x,f_k(x))` or :math:`y = A w` with :math:`A \in R^{npt \times m}` where :math:`A[i,j] = L(x_i,f_j(x_i))`.
25+
26+
This class can take specs of different linear maps L on functions :math:`f(x): x \rightarrow u`, with :math:`u \in R^{npt}`. We list here multiple options for illustration. The specification of the linear map ``lmap=gso.GLMAP(x,L)`` can be done with L given as either no spec, a function, or an array
27+
* if L is a user-defined callable L (function), then `lmap.eval(f)` returns :math:`L(x,u)` as specified by the user. If want a map, e.g.: :math:`L(x,f(x)) = e^x + x^3 f(x)`, one can use e.g. ``lmap = gso.GLMAP(x, lambda x, u: np.exp(x) + x**3 * u)``.
28+
* if L is a user-defined array L, i.e. :math:`L(x,u):=Lu`, (L shape needs to be :math:`(M,npt)`) then ``lmap.eval(f)`` returns :math:`Lu`. If we want a linear matrix map, say :math:`L = B` (shape :math:`(m,npt)` ), then can use either ``lmap = gso.GLMAP(x, B)`` or ``lmap = gso.GLMAP(x, lambda x, u: B@u)``.
29+
* if L is None or not specified, then an identiy map is implied, and ``lmap.eval(f)`` returns :math:`L(x,u) = u`; Thus, the following are all equivalent specs of the None option for L
30+
* ``lmap = gso.GLMAP(x)``
31+
* ``lmap = gso.GLMAP(x, np.eye(npt))``
32+
* ``lmap = gso.GLMAP(x, lambda x, u: u)``.
5133
'''
5234
def __init__(self,x,L=None,verbose=False):
5335
'''Initialization.
5436
5537
Args:
5638
x (np.ndarray) : 2d float data array of shape (npt,n), npt points each in R^n
57-
L : None (or absent)
58-
: 2d float array of shape (:,npt)
59-
: a callable user-provided function
39+
L (np.ndarray or callable or None) : 2d float array of shape :math:`(M,npt)` or a callable user-provided function or None.
6040
verbose (bool) : controls verbosity
6141
'''
6242
self.x = np.asarray(x,copy=True)
@@ -98,23 +78,24 @@ def __init__(self,x,L=None,verbose=False):
9878
else:
9979
self.Lmapfnc = lambda f, x, L : L(x,f(x))
10080

101-
def eval(self,f):
102-
glm = self.Lmapfnc(f,self.x,self.L)
81+
def eval(self, f):
82+
r'''Evaluate the map on function f.'''
83+
glm = self.Lmapfnc(f, self.x, self.L)
10384
return glm
10485

10586
class HMAT:
106-
'''Utilities class for H matrix construction.
87+
r'''Utilities class for H matrix construction.
10788
10889
Attributes:
10990
mgs (object) : MGS class object handle.
11091
m (int) : number of basis functions in expansion.
111-
mat (np.ndarray) : 3D array where H matrix is constructed.
92+
mat (np.ndarray) : 3D array where `H` matrix is constructed.
11293
level (int) : recursion level counter.
11394
verbose (bool) : controls verbosity.
114-
Fthmap (np.ndarray) : 2d int array, (i,j) entry 0/1 => corresponding (theta_i,theta_j) inner product has-not/has been evaluated.
115-
Fmap (np.ndarray) : 2d int array, (i,j) entry 0/1 => corresponding (phi_i,theta_j) inner product has-not/has been evaluated.
116-
Fthval (np.ndarray) : 2d array of (theta,theta) inner products.
117-
Fval (np.ndarray) : 2d array of (phi,theta) inner products.
95+
Fthmap (np.ndarray) : 2d int array, :math:`(i,j)` entry `0/1` => corresponding :math:`(\theta_i,\theta_j)` inner product has-not/has been evaluated.
96+
Fmap (np.ndarray) : 2d int array, :math:`(i,j)` entry `0/1` => corresponding :math:`(\phi_i,\theta_j)` inner product has-not/has been evaluated.
97+
Fthval (np.ndarray) : 2d array of :math:`(\theta,\theta)` inner products.
98+
Fval (np.ndarray) : 2d array of :math:`(\phi,\theta)` inner products.
11899
'''
119100

120101
def __init__(self,mgs_,verbose=False):
@@ -229,13 +210,13 @@ def fill(self,n,r,i1,i):
229210
return
230211

231212
class MGSV:
232-
'''Utilities class for V matrix construction.
213+
r'''Utilities class for :math:`V` matrix construction.
233214
234215
Attributes:
235216
m (int) : number of basis functions in expansion.
236-
mat (np.ndarray) : 2D (m x m)array where the V matrix is constructed.
217+
mat (np.ndarray) : 2D :math:`(m, m)` array where the :math:`V` matrix is constructed.
237218
verbose (bool) : controls verbosity.
238-
Smat (np.ndarray) : 3D (m x m x m) array where the S matrix is constructed.
219+
Smat (np.ndarray) : 3D :math:`(m, m, m)` array where the :math:`S` matrix is constructed.
239220
H (object) : pointer to HMAT object.
240221
'''
241222

@@ -282,19 +263,19 @@ def fill_row(self,i):
282263
return
283264

284265
class MGS:
285-
'''Modified Gram-Schmidt (MGS) class. Builds MGS object for functions.
266+
r'''Modified Gram-Schmidt (MGS) class. Builds MGS object for functions.
286267
287268
Attributes:
288269
m (int) : number of basis functions in expansion.
289-
phi (np.ndarray) : 1d (m) numpy array of starting functions.
290-
psi (np.ndarray) : 1d (m) numpy array of to be constructed orthogonal functions.
291-
tht (np.ndarray) : 1d (m) numpy array of to be constructed orthonormal functions.
270+
phi (np.ndarray) : 1d numpy array (size :math:`m`) of starting functions.
271+
psi (np.ndarray) : 1d numpy array (size :math:`m`) of to-be-constructed orthogonal functions.
272+
tht (np.ndarray) : 1d numpy array (size :math:`m`) of to-be-constructed orthonormal functions.
292273
Lmap (object) : pointer to local copy of Linear map and data object.
293274
modified (bool) : True/False for modified/original GS orthogonalization.
294-
V (np.ndarray) : 2d (m x m) numpy array ... the V matrix.
295-
Z (np.ndarray) : 2d (m x m) numpy array ... the Z matrix.
296-
Pmat (np.ndarray) : 2d (m x m) numpy array ... the P projection matrix
297-
lam (np.ndarray) : 1d (m-long) numpy array
275+
V (np.ndarray) : 2d :math:`(m, m)` numpy array ... the V matrix.
276+
Z (np.ndarray) : 2d :math:`(m, m)` numpy array ... the Z matrix.
277+
Pmat (np.ndarray) : 2d :math:`(m, m)` numpy array ... the P projection matrix
278+
lam (np.ndarray) : 1d numpy array of size :math:`m`.
298279
'''
299280

300281
def __init__(self,phi_,Lmap):
@@ -312,42 +293,35 @@ def __init__(self,phi_,Lmap):
312293
return
313294

314295
def iprod(self, pk, pl, **kwargs):
315-
'''Pair-wise inner product between (lists of) functions.
296+
r'''Pairwise inner product between (lists of) functions.
316297
317298
Args:
318-
Required inputs:
319-
pk : a list|tuple|numpy array of function pointers, or otherwise a function pointer
320-
pl : a list|tuple|numpy array of function pointers, or otherwise a function pointer
321-
Keyword argument inputs:
322-
k (int) : starting index in pk. Required iff pk is a list|tuple|array
323-
l (int) : starting index in pl. Required iff pl is a list|tuple|array
324-
Optional keyword argument inputs:
325-
kmxp (int) : (default: k+1) max-k plus 1, so that range(k,kmxp) goes over pk[k], ..., pk[kmxp-1]
326-
lmxp (int) : (default: l+1) max-l plus 1, so that range(l,lmxp) goes over pl[l], ..., pl[lmxp-1]
327-
verbose_warning (bool) : controls verbosity of warnings
328-
329-
Example use:
330-
say have pk list and pl single function, say:
331-
pk = [lambda x : 2*x, lambda x : x**2, lambda x : x**3]
332-
pl = lambda x : 10*x
333-
then : iprod(pk[3],pl) returns: [[<Lmap.eval(pk[3]),Lmap.eval(pl)>]], a 2d (1x1) numpy array
334-
and : iprod(pk,pl,k=1,kmxp=3) returns: [[<Lmap.eval(pk[1]),Lmap.eval(pl)>, <Lmap.eval(pk[2]),Lmap.eval(pl)>]]
335-
a 2d (1x2) numpy array
336-
alternately, say have two lists pk and pl with:
337-
pk = [lambda x : 2*x, lambda x : x**2, lambda x : x**3]
338-
pl = [lambda x : 10*x, lambda x : 3*x**5]
339-
then : iprod[pk,pl,k=0,kmxp=3,l=0,lmxp=2]
340-
returns:
341-
[ [<Lmap.eval(pk[0]),Lmap.eval(pl[0])>, <Lmap.eval(pk[0]),Lmap.eval(pl[1])>],
342-
[<Lmap.eval(pk[1]),Lmap.eval(pl[0])>, <Lmap.eval(pk[1]),Lmap.eval(pl[1])>],
343-
[<Lmap.eval(pk[2]),Lmap.eval(pl[0])>, <Lmap.eval(pk[2]),Lmap.eval(pl[1])>],
344-
]
345-
a 2d (3 x 2) numpy array
346-
NB. if x is an npt-long vector of data points, then for any of the above functions, say pk[2],
347-
Lmap.eval(pk[2]) will return a 2d (1xnpt) numpy array
348-
299+
pk : a list|tuple|numpy array of function pointers, or otherwise a function pointer
300+
pl : a list|tuple|numpy array of function pointers, or otherwise a function pointer
301+
kwargs : optional keyword arguments:
302+
303+
- k (int) : starting index in `pk`. Required iff `pk` is a list|tuple|array
304+
- l (int) : starting index in `pl`. Required iff `pl` is a list|tuple|array
305+
- kmxp (int) : (default: k+1) max-k plus 1, so that range(k,kmxp) goes over `pk[k], ..., pk[kmxp-1]`
306+
- lmxp (int) : (default: l+1) max-l plus 1, so that range(l,lmxp) goes over `pl[l], ..., pl[lmxp-1]`
307+
- verbose_warning (bool) : controls verbosity of warnings.
308+
349309
Returns:
350-
fklT (np.ndarray) : 2d float numpy array with kmxp-k rows and lmxp-l columns
310+
fklT (np.ndarray) : 2d float numpy array with `kmxp-k` rows and `lmxp-l` columns
311+
312+
Example:
313+
Say, we have `pk` list and `pl` single function
314+
315+
- ``pk = [lambda x : 2*x, lambda x : x**2, lambda x : x**3]``
316+
- ``pl = lambda x : 10*x``
317+
then
318+
319+
- ``iprod(pk[3],pl)`` returns: ``[[<Lmap.eval(pk[3]),Lmap.eval(pl)>]]``, a 2d `(1, 1)` numpy array and
320+
- ``iprod(pk,pl,k=1,kmxp=3)`` returns ``[[<Lmap.eval(pk[1]),Lmap.eval(pl)>, <Lmap.eval(pk[2]),Lmap.eval(pl)>]]``, a 2d `(1, 2)` numpy array.
321+
- ``iprod(pk,pl,k=0,kmxp=3,l=0,lmxp=2)`` returns ``[ [<Lmap.eval(pk[0]),Lmap.eval(pl[0])>, <Lmap.eval(pk[0]),Lmap.eval(pl[1])>], [<Lmap.eval(pk[1]),Lmap.eval(pl[0])>, <Lmap.eval(pk[1]),Lmap.eval(pl[1])>], [<Lmap.eval(pk[2]),Lmap.eval(pl[0])>, <Lmap.eval(pk[2]),Lmap.eval(pl[1])>]]`` a 2d `(3, 2)` numpy array.
322+
323+
NB. if x is an `npt`-long vector of data points, then for any of the above functions, say ``pk[2]``, ``Lmap.eval(pk[2])`` will return a 2d `(1, npt)` numpy array.
324+
351325
'''
352326

353327
k = kwargs.get('k')
@@ -389,13 +363,13 @@ def iprod(self, pk, pl, **kwargs):
389363

390364

391365
def bld_psi(self,i,Rinv):
392-
'''Build and return psi function for index i
366+
r'''Build and return \psi function for index `i`
393367
394368
Args:
395369
i (int) : row index
396370
Rinv (np.ndarray) : 2d float matrix
397371
Returns:
398-
lfnc (function) : psi function for index i
372+
lfnc (function) : :math:`\psi` function for index `i`
399373
'''
400374
def lfnc(x):
401375
arr = np.array([Rinv[i,j]*self.phi[j](x) for j in range(i+1)])
@@ -404,13 +378,13 @@ def lfnc(x):
404378
return lfnc
405379

406380
def bld_tht(self,i,laml):
407-
'''Build and return tht (theta) function for index i
381+
r'''Build and return tht (:math:`\theta`) function for index `i`
408382
409383
Args:
410384
i (int) : row index
411-
laml (float) : float specified scale factor to normalize psi[i]
385+
laml (float) : float specified scale factor to normalize :math:`\psi[i]`
412386
Returns:
413-
lfnc (function) : tht function for index i
387+
lfnc (function) : tht function for index `i`
414388
'''
415389
def lfnc(x):
416390
return laml * self.psi[i](x)
@@ -423,6 +397,7 @@ def ortho(self,modified=False,verbose=False,stage=0):
423397
modified (bool) : controls whether using modified Gram-Schmidt, or unmodified
424398
verbose (bool) : controls verbosity
425399
stage (int) : stage index within multistage Gram-Schmidt
400+
426401
Returns:
427402
Pmat (np.ndarray) : 2d float projection matrix
428403
tht (np.ndarray) : 1d array of tht function pointers
@@ -526,6 +501,7 @@ def ortho(self,modified=False,verbose=False,stage=0):
526501

527502
def ortho_check_phi(self,):
528503
'''Check orthonormality of phi functions
504+
529505
Returns:
530506
ipmat (np.ndarray) : float 2d array containing orthonormality check matrix output
531507
'''
@@ -536,6 +512,7 @@ def ortho_check_phi(self,):
536512

537513
def ortho_check(self,):
538514
'''Check orthogonality of tht functions
515+
539516
Returns:
540517
ipmat (np.ndarray) : float 2d array containing orthonormality check matrix output
541518
'''
@@ -545,7 +522,7 @@ def ortho_check(self,):
545522
return ipmat
546523

547524
class MMGS:
548-
'''
525+
r'''
549526
Multistage Modified Gram-Schmidt (MMGS) class.
550527
Builds MMGS object for functions.
551528
@@ -554,11 +531,11 @@ class MMGS:
554531
phi (np.ndarray) : 1d numpy array of starting functions
555532
phi_ (np.ndarray) : 1d numpy array of starting functions
556533
Lmap (object) : Linear map and data object
557-
Pmat (np.ndarray) : 2d (m,m) numpy array, the projection matrix P
558-
mgs (np.ndarray) : 1d (nstage,) array of MGS objects
559-
phia (np.ndarray) : 2d (nstage,m) numpy array of starting functions
560-
thta (np.ndarray) : 2d (nstage,m) numpy array of orthonormalized functions
561-
Parr (np.ndarray) : 3d (nstage,m,m) matrix, holds nstage P matrices
534+
Pmat (np.ndarray) : 2d `(m, m)` numpy array, the projection matrix `P`
535+
mgs (np.ndarray) : 1d `(nstage,)` array of MGS objects
536+
phia (np.ndarray) : 2d `(nstage, m)` numpy array of starting functions
537+
thta (np.ndarray) : 2d `(nstage, m)` numpy array of orthonormalized functions
538+
Parr (np.ndarray) : 3d `(nstage, m, m)` matrix, holds nstage P matrices
562539
'''
563540
def __init__(self,phi_,Lmap):
564541
'''Initialize.
@@ -572,11 +549,11 @@ def __init__(self,phi_,Lmap):
572549
return
573550

574551
def ortho(self,modified=False,nstage=1,verbose=False):
575-
'''Multiscale Modified Gram-Schmidt class orthonormalization
552+
r'''Multiscale Modified Gram-Schmidt class orthonormalization
576553
Runs multistage and/or Modified GS for functions
577554
578555
Returns:
579-
Pmat (np.ndarray) : float (m,m) aggregated projection matrix
556+
Pmat (np.ndarray) : float `(m,m)` aggregated projection matrix
580557
thta[-1] : 1d array of final tht functions
581558
'''
582559

0 commit comments

Comments
 (0)