Skip to content

Commit 1185700

Browse files
authored
Merge pull request #32 from sandialabs/30-implement-gs-orthogonalization
30 implement gs orthogonalization
2 parents 0131d85 + a3f850b commit 1185700

File tree

12 files changed

+845
-6
lines changed

12 files changed

+845
-6
lines changed
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

docs/auto_examples/ex_nn.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"name": "python",
3636
"nbconvert_exporter": "python",
3737
"pygments_lexer": "ipython3",
38-
"version": "3.12.7"
38+
"version": "3.13.7"
3939
}
4040
},
4141
"nbformat": 4,

docs/auto_examples/ex_nn.zip

0 Bytes
Binary file not shown.

docs/auto_examples/ex_pce.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
"name": "python",
7272
"nbconvert_exporter": "python",
7373
"pygments_lexer": "ipython3",
74-
"version": "3.12.7"
74+
"version": "3.13.7"
7575
}
7676
},
7777
"nbformat": 4,

docs/auto_examples/ex_pce.zip

0 Bytes
Binary file not shown.

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+
}

examples/ex_gso.py

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
#!/usr/bin/env python
2+
"""Example for testing Multistage Modified Gram-Schmidt (MMGS) orthogonalization for functions."""
3+
4+
import sys
5+
import argparse
6+
import numpy as np
7+
import copy
8+
import matplotlib.pyplot as plt
9+
10+
import pytuq.ftools.gso as gso
11+
12+
np.set_printoptions(precision=6, linewidth=200, suppress=False, threshold=np.inf)
13+
14+
###############################################################################
15+
###############################################################################
16+
###############################################################################
17+
# define some options
18+
#modified (bool) : specifies modified GS, or not
19+
#nstage (int) : number of stages, > 0
20+
#verbose (bool) : specifies if verbose or not
21+
#ndim (int) : specifies test case dimensionality, 1 or 2
22+
#plot (bool) : spefies if you want to make plots or not
23+
24+
parser = argparse.ArgumentParser(description="tmgs_Lmap arguments")
25+
26+
parser.add_argument('--modified', '-m', action='store_true', default=False, help='True/False as in modified or not.')
27+
parser.add_argument('--nstage' , '-s', type = int, default=1, help='Specify nstage.')
28+
parser.add_argument('--verbose' , '-v', action='store_true', default=False, help='Enable verbose output.')
29+
parser.add_argument('--ndim' , '-d', type = int, default=1, help='Specify nstage.')
30+
parser.add_argument('--plot' , '-p', action='store_true', default=False, help='Enable plotting.')
31+
args = parser.parse_args()
32+
33+
print('modified: ',args.modified)
34+
print('nstage: ',args.nstage)
35+
print('verbose: ',args.verbose)
36+
print('ndim: ',args.ndim)
37+
print('plot: ',args.plot)
38+
39+
modified = args.modified
40+
nstage = args.nstage
41+
verbose = args.verbose
42+
ndim = args.ndim
43+
plot = args.plot
44+
45+
# numpy rng initialization
46+
rng = np.random.default_rng(345126)
47+
np.random.seed(345126)
48+
49+
###############################################################################
50+
###############################################################################
51+
###############################################################################
52+
53+
#==============================================================================
54+
# specify the set of starting functions phi0, with shape (ntrm,)
55+
# and the data x, with shape (npt,ndim), and
56+
# npt is the number of data points, where each data point is ndim dimensions
57+
# in general can use any ndim as long as the appropriate phi0 functions are set up
58+
# here we have two example options, with ndim = 1 or 2
59+
60+
if ndim == 1: # 1d data case
61+
62+
# function to return 1d monomial phi[k](x) functions
63+
def phif_1d(k):
64+
def lfnc(x):
65+
return x**k
66+
return lfnc
67+
68+
# set number of terms: phi_0(x), phi_1(x), ... with phi_k(x) = x**k per above phif_1d()
69+
ntrm = 10
70+
phi0 = np.array([phif_1d(k) for k in range(ntrm)])
71+
72+
# define 1d data, an npt-long 1d array of points, each a scalar value
73+
npt = 50
74+
x = rng.uniform(-1,1,(npt))
75+
76+
elif ndim == 2: # 2d data case
77+
78+
# function to return 2d tensor-product of monomials phi[k0,k1](x) functions
79+
# where x is a 2-vector
80+
def phif_2d(k0,k1):
81+
def lfnc(x_):
82+
#return np.array([x[0] * x[1]**k1 for x in x_])
83+
return np.array([x[0]**k0 * x[1]**k1 for x in x_])
84+
return lfnc
85+
86+
nt = 3
87+
ntrm = nt*nt
88+
phi0 = np.array([phif_2d(k0,k1) for k0 in range(nt) for k1 in range(nt)])
89+
90+
# define 2d data, an npt x 2 array of npt points, each being a 2-vector
91+
npt = 100
92+
x = rng.uniform(-1,1,(npt,ndim))
93+
94+
else:
95+
print('not a valid ndim case option')
96+
sys.exit(1)
97+
98+
print('ntrm =',ntrm)
99+
100+
#==============================================================================
101+
# specify the linear map, which will also hold the x data
102+
103+
lmap = gso.GLMAP(x, verbose=verbose) # identity map
104+
# lmap = gso.GLMAP(x, 10*np.random.rand(int(npt/2),npt),verbose=verbose) # user matrix map
105+
# lmap = gso.GLMAP(x, lambda x, u: np.exp(x) * u, verbose=verbose) # user function map
106+
107+
#==============================================================================
108+
# do mmgs
109+
110+
# build mmgs object
111+
phi = copy.deepcopy(phi0)
112+
mmgs = gso.MMGS(phi,lmap)
113+
114+
# orthonormalize with multistage modified GS
115+
Pmat, tht = mmgs.ortho(modified=modified,nstage=nstage,verbose=verbose)
116+
117+
print('ortho check phi0 maxabs:',np.max(np.abs(mmgs.ortho_check_phi(0)-np.eye(mmgs.m))))
118+
print('ortho check tht maxabs:',np.max(np.abs(mmgs.ortho_check(nstage-1)-np.eye(mmgs.m))))
119+
120+
#==============================================================================
121+
# plotting diagnostics
122+
if plot:
123+
124+
if ndim == 1:
125+
126+
nx = 250
127+
xt = np.linspace(-1,1,nx)
128+
phixt = np.array([f(xt) for f in phi]).T
129+
thtxt = np.array([f(xt) for f in tht]).T
130+
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
131+
for q in range(mmgs.m):
132+
ax1.plot(xt, phixt[:,q], label='k:'+str(q))
133+
ax2.plot(xt, thtxt[:,q], label='k:'+str(q))
134+
ax1.set_title(r'$\phi$')
135+
ax2.set_title(r'$\theta$')
136+
for ax in (ax1, ax2):
137+
ax.scatter(x,[0]*npt,s=3,label='data')
138+
ax.set_xlabel(r'$x$')
139+
ax.grid(True)
140+
ax1.set_ylabel(r'$\phi_k(x)$')
141+
ax2.set_ylabel(r'$\theta_k(x)$')
142+
ax1.set_ylim(min(np.min(phixt),np.min(thtxt)),max(np.max(phixt),np.max(thtxt)))
143+
ax2.set_ylim(min(np.min(phixt),np.min(thtxt)),max(np.max(phixt),np.max(thtxt)))
144+
ax2.legend()
145+
ax2.legend(loc='upper right', bbox_to_anchor=(1.25, 1))
146+
plt.savefig('gso_1d.png')
147+
148+
elif ndim == 2:
149+
150+
X = np.arange(-2, 2, 0.1)
151+
Y = np.arange(-1, 1, 0.05)
152+
nX = X.shape[0]
153+
nY = Y.shape[0]
154+
X, Y = np.meshgrid(X, Y)
155+
XY = np.vstack((X.flatten(),Y.flatten())).T
156+
157+
Zphi = np.array([phi0[q](XY).reshape(nX,nY) for q in range(mmgs.m)])
158+
Ztht = np.array([mmgs.mgs[nstage-1].tht[q](XY).reshape(nX,nY) for q in range(mmgs.m)])
159+
160+
for q in range(mmgs.m):
161+
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6), subplot_kw={'projection': '3d'})
162+
#plt.suptitle('q: '+str(q)+', k0: '+str(int(q/nt))+', k1: '+str(q-int(q/nt)*nt))
163+
ax1.plot_surface(X, Y, Zphi[q], cmap='viridis')
164+
ax2.plot_surface(X, Y, Ztht[q], cmap='viridis')
165+
ax1.set_title(r'$\phi_'+str(q)+'$')
166+
ax2.set_title(r'$\theta_'+str(q)+'$')
167+
for ax in (ax1,ax2):
168+
ax.set_xlabel(r'$x$')
169+
ax.set_ylabel(r'$y$')
170+
ax1.set_zlabel(r'$\phi_'+str(q)+'(x,y)$')
171+
ax2.set_zlabel(r'$\theta_'+str(q)+'(x,y)$')
172+
ax1.set_zlim(min(np.min(Zphi[q]),np.min(Ztht[q])),max(np.max(Zphi[q]),np.max(Ztht[q])))
173+
ax2.set_zlim(min(np.min(Zphi[q]),np.min(Ztht[q])),max(np.max(Zphi[q]),np.max(Ztht[q])))
174+
plt.savefig(f'gso_2d_{q}.png')
175+
176+
else:
177+
print('not a valid ndim case option')
178+
sys.exit(1)
179+
#==============================================================================
180+
181+
print('done')
182+

examples/ex_integrate.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22

33
import numpy as np
4-
from pytuq.utils.integr import *
4+
from pytuq.ftools.integr import *
55

66
def single_gaussian(x, w=1.0):
77

src/pytuq/ftools/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env python
2+
3+

0 commit comments

Comments
 (0)