In [1]:
# gdapy06_00 clears all variables and import various modules
# you must run this cell first, before running any of others
# note that these examples use inverse theory techniques that
# are only covered in later chapters of the book
# History:
# 2023/04/24 - Created by W. Menke from Matlab version
# 2024/05/23 - Patches to accomodate new verions of numpy, scipy, matplotlib
# patches dot product to return scalar value
# A reset deletes any previously-created variables from memory
%reset -f
# import various packages
import numpy as np # matrices & etc
from matplotlib import pyplot as plt # general plotting
from matplotlib import patches # plotting shapes
from datetime import date # date and time arithmetic
from math import exp, pi, sin, cos, tan, sqrt, floor, log10, nan, log # math functions
import scipy.linalg as la # linear algebra functions
import os # operating system
import matplotlib.cm as cm
from matplotlib.colors import ListedColormap
import scipy.signal as sg
import scipy.stats as st
import scipy.sparse.linalg as las
from scipy import sparse
import matplotlib
# function to make a numpy N-by-1 column vector
# c=eda_cvec(v1, v2, ...) from a list of several
# array-like entities v1, v2, including a number
# a list of numbers, a tuple of numbers, an N-by-0 np array
# and a N-by-1 np array. The function
# also insures that, if v is an np array, that
# c is a copy, as contrasted to a view, of it
# It promotes integers to floats, and integers
# and floats to complex, by context.
# This version concatenates many argments,
# whereas c=eda_cvec1(v1) takes just one argiment.
# I recommend always using eda_cvec(v1, v2, ...)
def gda_cvec(*argv):
t = int;
Nt = 0;
for a in argv:
v = gda_cvec1(a);
N,M = np.shape(v);
Nt = Nt + N;
if( N==0 ):
continue; # skip vector of zero length
if (t==int) and isinstance(v[0,0],float):
t=float;
elif isinstance(v[0,0],complex):
t=complex;
w = np.zeros((Nt,1),dtype=t);
Nt = 0;
for a in argv:
v = gda_cvec1(a);
N,M = np.shape(v);
w[Nt:Nt+N,0:1] = v; # patch 20230418 was #w[Nt:Nt+N,0] = v[0:N,0];
Nt = Nt + N;
return w;
# function to make a numpy N-by-1 column vector
# c=gda_cvec1(v) from entity v that is array-like,
# including a number, a list of numbers, a tuple
# of numbers, an N-by-0 np array and a N-by1 np array.
# It promotes integers to floats, and integers
# and floats to complex, by context. The function
# also insures that, if v is an np array, that
# c is a copy, as contrasted to a view, of it.
# This version takes just one input argment.
# whereas c=gda_cvec(v1,v2,...) concatenates
# many argiments.
def gda_cvec1(v):
if isinstance(v, int) or isinstance(v, np.int32):
w = np.zeros((1,1),dtype=int);
w[0,0] = v;
return w;
elif isinstance(v, float):
w = np.zeros((1,1),dtype=float);
w[0,0] = v;
return w;
elif isinstance(v, complex):
w = np.zeros((1,1),dtype=complex);
w[0,0] = v;
return w;
elif isinstance(v, np.ndarray):
s = np.shape(v);
if len(s) == 1:
return np.copy(np.reshape(v,(s[0],1)));
else:
[r,c]=s;
if( c==1 ):
return(np.copy(v));
elif(r==1):
return(np.copy(v.T));
else:
raise TypeError("gda_cvec: %d by %d ndarray not allowed" % (r, c));
elif isinstance(v, list):
r = len(v);
t = int;
for vi in v:
if isinstance(vi,int) or isinstance(vi, np.int32): #patch v->vi 20230418
pass;
elif isinstance(vi,float):
t=float;
elif isinstance(vi,complex):
t=complex;
break;
else:
raise TypeError("gda_cvec: list contains unsupported type %s" % type(vi));
w = np.zeros((r,1),dtype=t);
w[:,0] = np.array(v); # patch v -> np.array(v)
return w;
elif isinstance(v, tuple):
r = len(v);
t = int;
for vi in v:
if isinstance(vi,int) or isinstance(vi, np.int32): #patch v->vi 20230418
pass;
elif isinstance(vi,float):
t=float;
elif isinstance(vi,complex):
t=complex;
break;
else:
raise TypeError("gda_cvec: tuple contains unsupported type %s" % type(vi));
w = np.zeros((r,1),dtype=t);
w[:,0] = np.array(list(v)); # patch v -> np.array(list(v));
return w;
else:
raise TypeError("gda_cvec: %s not supported" % type(v));
# gda_draw function makes a "pictorial matrix equation"
# arguments are vectors, matrices and strings
# which are plotted in the order that the appear
# except that strings starting with 'title ' are plotted
# under the subseqeunt matrix or vector
# always returns a status of 1
def gda_draw(*argv):
DOCOLOR=True;
if( DOCOLOR ):
bwcmap = matplotlib.colormaps['jet'];
else:
bw = np.zeros((256,4));
v = 0.9*(256 - np.linspace( 0, 255, 256 ))/255;
bw[:,0] = v;
bw[:,1] = v;
bw[:,2] = v;
bw[:,3] = np.ones(256);
bwcmap = ListedColormap(bw);
# size of plot
W = 16;
H = 4;
fig1 = plt.figure(1);
# figsize width and height in inches
fig1.set_size_inches(W,H);
ax1 = plt.subplot(1,1,1);
plt.axis([0, W, -H/2, H/2]);
plt.axis('off');
LM = W/6; # matrix width and heoght
LV = W/40; # vector width
FS = 0.12; # character width
TO = 0.4; # title vertical offset
SP = 0.2; # space between objects
LS = 0.2; # leading space
p = LS; # starting x-position
istitle=0; # flags presence of a title
for a in argv:
if isinstance(a,np.ndarray):
sh = np.shape(a);
if len(sh) == 1: # conversion to nx1 array
n = sh[0];
m = 1;
ap = a;
a = np.zeros((n,1));
a[:,0] = ap;
else:
n = sh[0];
m = sh[1];
if m==1:
pold=p;
left=p;
right=p+LV;
bottom=-LM/2;
top=LM/2;
plt.imshow( a, cmap=bwcmap, vmin=np.min(a), vmax=np.max(a), extent=(left,right,bottom,top) );
p = p+LV;
pm = (p+pold)/2;
if istitle:
plt.text(pm,-(LM/2)-TO,titlestr,horizontalalignment='center');
istitle=0;
p = p+SP;
else:
pold=p;
left=p;
right=p+LM;
bottom=-LM/2;
top=LM/2;
plt.imshow( a, cmap=bwcmap, vmin=np.min(a), vmax=np.max(a), extent=(left,right,bottom,top) );
p = p+LM;
pm = (p+pold)/2;
if istitle:
plt.text(pm,-(LM/2)-TO,titlestr,horizontalalignment='center');
istitle=0;
p = p+SP;
elif isinstance(a,str):
ns = len(a);
istitle=0;
if( ns>=6 ):
if 'title ' in a[0:6]:
istitle=1;
titlestr=a[6:];
if( istitle != 1):
plt.text(p,0,a);
p = p + ns*FS + SP;
plt.show();
return 1;
# bandpass filter, used in seismological example, but hand
# in a variety of settings involving time series
def gda_chebyshevfilt(d, Dt, flow, fhigh):
# (dout,u,v)=gda_chebyshevfilt(d, Dt, flow, fhigh);
# chebyshev IIR bandpass filter
# d - input array of data
# Dt - sampling interval
# flow - low pass frequency, Hz
# fhigh - high pass frequency, Hz
# dout - output array of data
# u - the numerator filter
# v - the denominator filter
# these filters can be used again using dout=filter(u,v,din);
# make sure input timeseries is a column vector
s = np.shape(d);
N = s[0];
if(N==1):
dd = np.zeros((N,1));
dd[:,0] = d;
else:
dd=d;
# sampling rate
rate=1/Dt;
# ripple parameter, set to ten percent
ripple=0.1;
# normalise frequency
fl=2.0*flow/rate;
fh=2.0*fhigh/rate;
# center frequency
cf = 4 * tan( (fl*pi/2) ) * tan( (fh*pi/2) );
# bandwidth
bw = 2 * ( tan( (fh*pi/2) ) - tan( (fl*pi/2) ) );
# ripple parameter factor
rpf = sqrt((sqrt((1.0+1.0/(ripple*ripple))) + 1.0/ripple));
a = 0.5*(rpf-1.0/rpf);
b = 0.5*(rpf+1.0/rpf);
u=np.zeros((5,1));
v=np.zeros((5,1));
theta = 3*pi/4;
sr = a * cos(theta);
si = b * sin(theta);
es = sqrt(sr*sr+si*si);
tmp= 16.0 - 16.0*bw*sr + 8.0*cf + 4.0*es*es*bw*bw - 4.0*bw*cf*sr + cf*cf;
v[0,0] = 1.0;
v[1,0] = 4.0*(-16.0 + 8.0*bw*sr - 2.0*bw*cf*sr + cf*cf)/tmp;
v[2,0] = (96.0 - 16.0*cf - 8.0*es*es*bw*bw + 6.0*cf*cf)/tmp;
v[3,0] = (-64.0 - 32.0*bw*sr + 8.0*bw*cf*sr + 4.0*cf*cf)/tmp;
v[4,0] = (16.0 + 16.0*bw*sr + 8.0*cf + 4.0*es*es*bw*bw + 4.0*bw*cf*sr + cf*cf)/tmp;
tmp = 4.0*es*es*bw*bw/tmp;
u[0,0] = tmp;
u[1,0] = 0.0;
u[2,0] = -2.0*tmp;
u[3,0] = 0.0;
u[4,0] = tmp;
dout = sg.lfilter(u.ravel(),v.ravel(),dd.ravel());
return (gda_cvec(dout),gda_cvec(u),gda_cvec(v));
# function to perform the multiplication FT (F v)
def gdaFTFmul(v):
# this function is used by bicongugate gradient to
# solve the generalized least squares problem Fm=F.
# Note that "F" must be called "gdaFsparse".
global gdaFsparse;
s = np.shape(v);
if(len(s)==1):
vv = np.zeros((s[0],1));
vv[:,0] = v;
else:
vv=v;
# weirdly, "*" multiplies sparse matrices just fine
temp = gdaFsparse*vv;
return gdaFsparse.transpose()*temp;
# function to perform the multiplication FT (F v)
def gda_FTFmul(v):
# this function is used by bicongugate gradient to
# solve the generalized least squares problem Fm=F.
# Note that "F" must be called "gdaFsparse".
global gdaFsparse;
s = np.shape(v);
if(len(s)==1):
vv = np.zeros((s[0],1));
vv[:,0] = v;
else:
vv=v;
# weirdly, "*" multiplies sparse matrices just fine
temp = gdaFsparse*vv;
return gdaFsparse.transpose()*temp;
# function to perform the multiplication FT f
def gda_FTFrhs(f):
# this function is used by bicongugate gradient to
# solve the generalized least squares problem Fm=F.
# Note that "F" must be called "gdaFsparse".
global gdaFsparse;
return gdaFsparse.transpose()*f;
def gda_matrixmin(E):
E1 = np.min(E,axis=0);
k = np.argmin(E,axis=0);
Emin = np.min(E1);
ic = np.argmin(E1);
ir = k[ic];
return ir, ic, Emin;
In [2]:
# gdapy06_01
# data point inside of 3D box with 1:1:1 refernce line
# this version differs from the MATLAB(R) version in that it uses
# a wirefram grid to plot a sphere, as contrasted to plotting a
# shaded patch.
print("gdapy06_01");
# x-axis
Nx = 31;
xmin = 0.0;
xmax = 5.0;
Dx = (xmax-xmin)/(Nx-1);
x = gda_cvec(xmin + Dx*np.linspace(0,Nx-1,Nx));
# y-axis
Ny = 31;
ymin = 0.0;
ymax = 5.0;
Dy = (ymax-ymin)/(Ny-1);
y = gda_cvec(ymin + Dy*np.linspace(0,Ny-1,Ny));
# z-axis
Nz = 31;
zmin = 0;
zmax = 5;
Dz = (zmax-zmin)/(Nz-1);
z = gda_cvec(zmin + Dz*np.linspace(0,Nz-1,Nz));
# the point is at a randomly chosen point in d-space
# using a Normal distribution with specified mean and variance
rbar = np.random.normal(loc=2.5,scale=0.5,size=(3,1));
# setup for 3D figure
fig1 = plt.figure(1,figsize=(12,5)); # smallish figure
ax = fig1.add_subplot(111, projection='3d');
plt.axis('off');
plt.grid(b=None);
ax.axes.set_xlim3d(left=xmin, right=xmax);
ax.axes.set_ylim3d(bottom=ymin, top=ymax);
ax.axes.set_zlim3d(bottom=zmin, top=zmax);
# improvise 3D box
ax.plot3D( gda_cvec(xmin,xmin).ravel(), gda_cvec(ymin,ymin).ravel(), gda_cvec(zmin,zmax).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmin,xmin).ravel(), gda_cvec(ymin,ymax).ravel(), gda_cvec(zmin,zmin).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmin,xmax).ravel(), gda_cvec(ymin,ymin).ravel(), gda_cvec(zmin,zmin).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmax,xmax).ravel(), gda_cvec(ymax,ymax).ravel(), gda_cvec(zmax,zmin).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmax,xmax).ravel(), gda_cvec(ymax,ymin).ravel(), gda_cvec(zmax,zmax).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmax,xmin).ravel(), gda_cvec(ymax,ymax).ravel(), gda_cvec(zmax,zmax).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmax,xmin).ravel(), gda_cvec(ymin,ymin).ravel(), gda_cvec(zmax,zmax).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmax,xmax).ravel(), gda_cvec(ymin,ymin).ravel(), gda_cvec(zmax,zmin).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmin,xmin).ravel(), gda_cvec(ymax,ymin).ravel(), gda_cvec(zmax,zmax).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmin,xmin).ravel(), gda_cvec(ymax,ymax).ravel(), gda_cvec(zmax,zmin).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmax,xmax).ravel(), gda_cvec(ymax,ymin).ravel(), gda_cvec(zmin,zmin).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmax,xmin).ravel(), gda_cvec(ymax,ymax).ravel(), gda_cvec(zmin,zmin).ravel(), "k-", lw=2 );
# plot 1:1:1 line
ax.plot3D( gda_cvec(0.0,5.0).ravel(), gda_cvec(0.0,5.0).ravel(), gda_cvec(0.0,5.0).ravel(), "b-", lw=3 );
# draw sphere using wireframe technique
Nu = 21;
u0 = 2.0*pi*np.linspace(0,Nu-1,Nu)/(Nu-1);
Nv = 11;
v0 = 2.0*pi*np.linspace(0,Nv-1,Nv)/(Nv-1);
u, v = np.meshgrid(u0,v0);
diameter=0.2;
x = diameter*np.cos(u)*np.sin(v)+rbar[0,0];
y = diameter*np.sin(u)*np.sin(v)+rbar[1,0];
z = diameter*np.cos(v)+rbar[2,0];
ax.plot_wireframe(x, y, z, color="r")
plt.show();
gdapy06_01
In [3]:
# gdapy06_02
# 3D Normal pdf plotted along along 1:1:1 line
# this version differs from the MATLAB(R) version in that it uses
# a dots to visualize the pdf, whereas MATLAB(R) uses multiple surface
print('gdapy06_02\n');
# x-axis
Nx = 31;
xmin = 0.0;
xmax = 5.0;
Dx = (xmax-xmin)/(Nx-1);
x = gda_cvec(xmin + Dx*np.linspace(0,Nx-1,Nx));
# y-axis
Ny = 31;
ymin = 0.0;
ymax = 5.0;
Dy = (ymax-ymin)/(Ny-1);
y = gda_cvec(ymin + Dy*np.linspace(0,Ny-1,Ny));
# z-axis
Nz = 31;
zmin = 0;
zmax = 5;
Dz = (zmax-zmin)/(Nz-1);
z = gda_cvec(zmin + Dz*np.linspace(0,Nz-1,Nz));
# setup for 3D figure
fig1 = plt.figure(1,figsize=(12,5)); # smallish figure
ax = fig1.add_subplot(111, projection='3d');
plt.axis('off');
plt.grid(b=None);
ax.axes.set_xlim3d(left=xmin, right=xmax);
ax.axes.set_ylim3d(bottom=ymin, top=ymax);
ax.axes.set_zlim3d(bottom=zmin, top=zmax);
# improvise 3D box
ax.plot3D( gda_cvec(xmin,xmin).ravel(), gda_cvec(ymin,ymin).ravel(), gda_cvec(zmin,zmax).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmin,xmin).ravel(), gda_cvec(ymin,ymax).ravel(), gda_cvec(zmin,zmin).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmin,xmax).ravel(), gda_cvec(ymin,ymin).ravel(), gda_cvec(zmin,zmin).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmax,xmax).ravel(), gda_cvec(ymax,ymax).ravel(), gda_cvec(zmax,zmin).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmax,xmax).ravel(), gda_cvec(ymax,ymin).ravel(), gda_cvec(zmax,zmax).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmax,xmin).ravel(), gda_cvec(ymax,ymax).ravel(), gda_cvec(zmax,zmax).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmax,xmin).ravel(), gda_cvec(ymin,ymin).ravel(), gda_cvec(zmax,zmax).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmax,xmax).ravel(), gda_cvec(ymin,ymin).ravel(), gda_cvec(zmax,zmin).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmin,xmin).ravel(), gda_cvec(ymax,ymin).ravel(), gda_cvec(zmax,zmax).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmin,xmin).ravel(), gda_cvec(ymax,ymax).ravel(), gda_cvec(zmax,zmin).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmax,xmax).ravel(), gda_cvec(ymax,ymin).ravel(), gda_cvec(zmin,zmin).ravel(), "k-", lw=2 );
ax.plot3D( gda_cvec(xmax,xmin).ravel(), gda_cvec(ymax,ymax).ravel(), gda_cvec(zmin,zmin).ravel(), "k-", lw=2 );
# plot 1:1:1 line
ax.plot3D( gda_cvec(0.0,5.0).ravel(), gda_cvec(0.0,5.0).ravel(), gda_cvec(0.0,5.0).ravel(), "b-", lw=3 );
# Normal pdf parameter
rbar = gda_cvec(2.5, 2.5, 2.5); # center
sd=0.5; # sqrt(variance);
# render normal pdf as a bunch of dots in 3D space
Nr = 10;
r = gda_cvec(0.05, 0.1, 0.15, 0.2, 0.3, 0.3, 0.5, 0.8); # radius of dots
Nth = 10;
Dth = 2*pi/Nth;
Nph = 5;
Dph = pi/Nph;
for ith in range(Nth): # loop over horizontal angle
th = Dth*ith;
sth = sin(th);
cth = cos(th);
for iph in range(Nph): # loop over vertical angle
ph = Dph*iph;
sph = sin(ph);
cph = cos(ph);
xr = rbar[0,0]+sin(th)*sin(ph)*r;
yr = rbar[1,0]+cos(th)*sin(ph)*r;
zr = rbar[2,0]+cos(ph)*r;
ax.scatter(xr, yr, zr, marker=".", color="r");
plt.show();
gdapy06_02
In [4]:
# gdapy06_03
# Likelihood surface for mean/variance
print("gdapy06_03");
# random data
N = 100;
meantrue=2.5;
sigmatrue=1.5;
d = np.random.normal(loc=meantrue,scale=sigmatrue,size=(N,1));
# m1-axis, with m1=mean
Nm = 51;
mmin = 1;
mmax = 5.0;
Dm = (mmax-mmin)/(Nm-1);
m = gda_cvec(mmin + Dm*np.linspace(0,Nm-1,Nm));
#% s-axis, with s=sqrt(variance)
Ns = 51;
smin = 1;
smax = 5.0;
Ds = (smax-smin)/(Ns-1);
s = gda_cvec(smin + Ds*np.linspace(0,Ns-1,Ns));
# (m,s) grid
[X,Y]=np.meshgrid( m, s);
# likelihood surface
L=np.zeros((Nm,Ns));
# tabulate likelihood surface
# Normal P = (1/sqrt(2pi)) * (1/s) * exp( -0.5 (d-m)^2 / s^2 )
# L = -0.5log(2*pi) - log(s) - ( -0.5 (d-m)^2 / s^2 )
for i in range(Nm):
for j in range(Ns):
mp=X[i,j];
sp=Y[i,j];
L[i,j] = -N*log(2*pi)/2 - N*log(sp) - 0.5*np.sum(np.power(d-mp,2))/(sp**2);
# find (i,j) of point of maximum
Li, Lj, Lmax = gda_matrixmin(-L);
Lmax=-Lmax;
# minimum for plotting purposes
i, j, Lmin = gda_matrixmin(L);
# maximum likelihood point
mbest = X[Li,Lj];
sbest = Y[Li,Lj];
print("True: mean %f sigma %f" % (meantrue,sigmatrue) );
print("Est: mean %f sigma %f Likelihood %f" % (mbest,sbest,Lmax) );
fig1 = plt.figure(1,figsize=(12,5)); # smallish figure
ax1 = fig1.add_subplot(111, projection='3d');
mycmap=matplotlib.colormaps['jet'];
surf = ax1.plot_surface(X, Y, L, cmap=mycmap);
fig1.colorbar(surf, shrink=0.5);
Dm=0.4;
Ds=0.4;
DL=50.0;
ax1.plot3D( gda_cvec(mbest,mbest).ravel(), gda_cvec(sbest,sbest).ravel(), gda_cvec(Lmin,Lmax).ravel(), "k-", lw=3 );
ax1.plot3D( gda_cvec(mbest,mbest).ravel(), gda_cvec(sbest-Ds,sbest+Ds).ravel(), gda_cvec(Lmin,Lmin).ravel(), "k-", lw=3 );
ax1.plot3D( gda_cvec(mbest-Dm,mbest+Dm).ravel(), gda_cvec(sbest,sbest).ravel(), gda_cvec(Lmin,Lmin).ravel(), "k-", lw=3 );
ax1.plot3D( gda_cvec(meantrue,meantrue).ravel(), gda_cvec(sigmatrue-Ds,sigmatrue+Ds).ravel(), gda_cvec(Lmin,Lmin).ravel(), "r-", lw=1 );
ax1.plot3D( gda_cvec(meantrue-Dm,meantrue+Dm).ravel(), gda_cvec(sigmatrue,sigmatrue).ravel(), gda_cvec(Lmin,Lmin).ravel(), "r-", lw=1 );
plt.xlabel("mean");
plt.ylabel("sigma");
plt.show();
print("Caption: Depiction of likelihood surface L(mean,sigma) (colors)");
print("with estimated value (black) and true value (red) superimposed.");
gdapy06_03 True: mean 2.500000 sigma 1.500000 Est: mean 2.280000 sigma 1.400000 Likelihood -175.567400
Caption: Depiction of likelihood surface L(mean,sigma) (colors) with estimated value (black) and true value (red) superimposed.
In [5]:
# gdapy06_04
# examples of probability density function p(d1,d2)
# one is peaked, the other had a ridge
print("gdapy06_04");
# d1-axis
Nd1 = 51;
d1min = 0.0;
d1max = 5.0;
Dd1 = (d1max-d1min)/(Nd1-1);
d1 = gda_cvec(d1min + Dd1*np.linspace(0,Nd1-1,Nd1));
# d2-axis
Nd2 = 51;
d2min = 0.0;
d2max = 5.0;
Dd2 = (d2max-d2min)/(Nd2-1);
d2 = gda_cvec(d2min + Dd2*np.linspace(0,Nd2-1,Nd2));
# (d1,d2) grid
X, Y = np.meshgrid( d1, d2);
# distribution 1, has a peak
P1=np.zeros((Nd1,Nd2));
dbar = gda_cvec(2.5, 2.5);
sd1 = 0.5;
sd2 = 0.5;
C = np.diag( gda_cvec(sd1, sd2).ravel() );
CI = la.inv(C);
DC = la.det(C);
norm = (1.0/(2.0*pi)) * (1.0/sqrt(DC));
for i in range(Nd1):
for j in range(Nd2):
d = gda_cvec( X[i,j], Y[i,j] ) - dbar;
r2 = np.matmul(d.T,np.matmul(CI,d)); r2=r2[0,0];
P1[i,j] = norm*exp( -0.5 * r2 );
# for test purposes
# A = Dd1*Dd2*sum(sum(P1)
# distribution 2, ridge
# Note distribution not normalizable
P2=np.zeros((Nd1,Nd2));
sda = 0.5;
d0a = gda_cvec(2.5, 2.5);
w = np.ones((2,1));
for i in range(Nd1):
for j in range(Nd2):
dr =gda_cvec( X[i,j]-d0a[0,0], Y[i,j]-d0a[1,0] );
r2= np.matmul(dr.T,w)**2; r2=r2[0,0];
P2[i,j] = 0.2*exp(-0.5*r2/sda);
# plot
fig1 = plt.figure(1,figsize=(12,5)); # smallish figure
ax1 = fig1.add_subplot(121, projection='3d');
mycmap=matplotlib.colormaps['jet'];
surf = ax1.plot_surface(X, Y, P1, cmap=mycmap);
plt.xlabel("x");
plt.ylabel("y");
ax2 = fig1.add_subplot(122, projection='3d');
mycmap=matplotlib.colormaps['jet'];
surf = ax2.plot_surface(X, Y, P2, cmap=mycmap);
plt.xlabel("x");
plt.ylabel("y");
plt.show();
print("Caption: (left) Pdf p(x1,x2) with a peak. (right) Pdf");
print("p(x1,x2) with a ridge.");
gdapy06_04
Caption: (left) Pdf p(x1,x2) with a peak. (right) Pdf p(x1,x2) with a ridge.
In [6]:
# gdapy06_05
# examples of probability density function p(m1,m2)
# uncorrelated, equal variance, one with small
# variance, the other with large variance
print("gdapy06_05");
# m1-axis
Nm1 = 51;
m1min = 0.0;
m1max = 5.0;
Dm1 = (m1max-m1min)/(Nm1-1);
m1 = gda_cvec(m1min + Dm1*np.linspace(0,Nm1-1,Nm1));
# m2-axis
Nm2 = 51;
m2min = 0;
m2max = 5.0;
Dm2 = (m2max-m2min)/(Nm2-1);
m2 = gda_cvec(m2min + Dm2*np.linspace(0,Nm2-1,Nm2));
# setup for distribution 1, small variance
P1=np.zeros((Nm1,Nm2));
mbar1 = gda_cvec(2.5, 2.5);
sd1 = 0.5;
C1 = np.diag( gda_cvec(sd1**2, sd1**2).ravel() );
CI1 = la.inv(C1);
DC1 = la.det(C1);
# setup for distributions 2, large variance
P2=np.zeros((Nm1,Nm2));
mbar2 = gda_cvec(2.5, 2.5);
sd2 = 1.0;
C2 = np.diag( gda_cvec( sd2**2, sd2**2).ravel() );
CI2 = la.inv(C2);
DC2 = la.det(C2);
# make distributions
norm1 = (1/(2*pi)) * (1/sqrt(DC1));
norm2 = (1/(2*pi)) * (1/sqrt(DC2));
for i in range(Nm1):
for j in range(Nm2):
x1 =gda_cvec(m1[i,0], m2[j,0]) - mbar1;
x2 =gda_cvec(m1[i,0], m2[j,0]) - mbar2;
r2 = np.matmul(x1.T,np.matmul(CI1,x1)); r2=r2[0,0];
P1[i,j] = norm1*exp( -0.5 * r2 );
r2 = np.matmul(x1.T,np.matmul(CI2,x1)); r2=r2[0,0];
P2[i,j] = norm2*exp( -0.5 * r2 );
# for test purposes
# A1 = Dd1*Dd2*sum(sum(P1));
# A2 = Dd1*Dd2*sum(sum(P2));
# draw distributions
gda_draw(P1," ",P2 );
print("Caption: (Left) Pdf p(m1,m2) with small and equal sigmas. (right)");
print("(Right) Pdf p(m1,m2) with large and equal sigmas. (right)");
gdapy06_05
Caption: (Left) Pdf p(m1,m2) with small and equal sigmas. (right) (Right) Pdf p(m1,m2) with large and equal sigmas. (right)
In [7]:
# gdapy06_06
# examples of probability density function p(m1,m2)
# unequal variance, uncorrelated
print("gdapy06_06");
# m1-axis
Nm1 = 51;
m1min = 0.0;
m1max = 5.0;
Dm1 = (m1max-m1min)/(Nm1-1);
m1 = gda_cvec( m1min + Dm1*np.linspace(0.0,Nm1-1,Nm1));
# m2-axis
Nm2 = 51;
m2min = 0.0;
m2max = 5.0;
Dm2 = (m2max-m2min)/(Nm2-1);
m2 = gda_cvec( m2min + Dm2*np.linspace(0.0,Nm2-1,Nm2));
# setup for distribution 1, C11<C22
P1=np.zeros((Nm1,Nm2));
mbar1 = gda_cvec(2.5, 2.5);
sd1 = 0.5;
sd2 = 1.0;
C1 = np.diag( gda_cvec(sd1**2, sd2**2).ravel() );
CI1 = la.inv(C1);
DC1 = la.det(C1);
# normalization
norm1 = (1.0/(2.0*pi)) * (1.0/sqrt(DC1));
# build distribution
for i in range(Nm1):
for j in range(Nm2):
x1 = gda_cvec( m1[i,0], m2[j,0] ) - mbar1;
r2 = np.matmul(x1.T,np.matmul(CI1,x1)); r2=r2[0,0];
P1[i,j] = norm1*exp( -0.5 * r2 );
# for test purposes
# A1 = Dd1*Dd2*np.sum(P1);
gda_draw(P1);
print("Caption: Pdf p(m1,m2) with unequal sigmas and zero covarince.");
gdapy06_06
Caption: Pdf p(m1,m2) with unequal sigmas and zero covarince.
In [8]:
# gdapy06_07
# examples of probability density function p(m1,m2)
# one is a ridge, the other is Normal but mimics a ridge
print("gdapy06_07");
# m1-axis
Nm1 = 51;
m1min = 0.0;
m1max = 5.0;
Dm1 = (m1max-m1min)/(Nm1-1);
m1 = gda_cvec(m1min + Dm1*np.linspace(0,Nm1-1,Nm1));
# m2-axis
Nm2 = 51;
m2min = 0.0;
m2max = 5.0;
Dm2 = (m2max-m2min)/(Nm2-1);
m2 = gda_cvec(m2min + Dm2*np.linspace(0,Nm2-1,Nm2));
# setup for distribution 1, Normal
P1=np.zeros((Nm1,Nm2));
mbar1 = gda_cvec(2.5, 2.5);
sd12 = 2.0;
cov = 2.0-0.1;
C1 = np.array( [ [sd12, cov], [cov, sd12] ] );
CI1 = la.inv(C1);
DC1 = la.det(C1);
norm1 = (1.0/(2.0*pi)) * (1.0/sqrt(DC1));
# calculate pdf
for i in range(Nm1):
for j in range(Nm2):
x1 = gda_cvec( m1[i,0], m2[j,0] ) - mbar1;
r2 = np.matmul(x1.T,np.matmul(CI1,x1)); r2=r2[0,0];
P1[i,j] = norm1*exp( -0.5 * r2 );
# setup for distribution 2, ridge
# Note distribution not normalizable
P2=np.zeros((Nm1,Nm2));
sda2 = 0.5;
d0a = gda_cvec(2.5, 2.5);
w = gda_cvec(1.0,-1.0);
for i in range(Nm1):
for j in range(Nm2):
dr = gda_cvec( m1[i,0], m2[j,0] ) - d0a;
r2 = np.matmul(dr.T,w)**2; r2=r2[0,0];
P2[i,j] = 0.2*exp(-0.5*r2/sda2);
# plot distributions
gda_draw(P2, " ", P1 );
gdapy06_07
In [9]:
# gdapy06_08
# example of probability density function p(m1,m2)
# implements inequality constraint m1<m2
print("gdapy06_08");
# m1-axis
Nm1 = 51;
m1min = 0.0;
m1max = 5.0;
Dm1 = (m1max-m1min)/(Nm1-1);
m1 = gda_cvec(m1min + Dm1*np.linspace(0,Nm1-1,Nm1));
# m2-axis
Nm2 = 51;
m2min = 0.0;
m2max = 5.0;
Dm2 = (m2max-m2min)/(Nm2-1);
m2 = gda_cvec(m2min + Dm2*np.linspace(0,Nm2-1,Nm2));
# compute pdf
P1=np.zeros((Nm1,Nm2));
for i in range(Nm1):
for j in range(Nm2):
P1[i,j] = float(m1[i,0]<=m2[j,0]);
# plot distribution
gda_draw(P1 );
print("Caption: Pdf p(m1,m2) implementing the inequality constraint m1<m2.");
gdapy06_08
Caption: Pdf p(m1,m2) implementing the inequality constraint m1<m2.
In [10]:
# gdapy06_09
# relative entropy of onenormsl pdf p(m)
# with respect to another q(m)
print("gdapy06_09");
# m-axis
N=101;
mmin = -25;
mmax = 25;
Dm = (mmax-mmin)/(N-1);
m = gda_cvec(mmin + Dm*np.linspace(0,N-1,N));
# p(m) = pA(m)
mbarp = 0.0;
sigmamp = 1;
p = (1.0/(sqrt(2.0*pi)*sigmamp))*np.exp(-(np.power(m-mbarp,2)/(2.0*sigmamp*sigmamp)));
normp = Dm*np.sum(p);
# q(m) = pN(m)
mbarq = 0.0;
sigmamq = 5.0;
q = (1.0/(sqrt(2.0*pi)*sigmamq))*np.exp(-np.power(m-mbarq,2)/(2.0*sigmamq*sigmamq));
normq = Dm*np.sum(q);
# plot
fig1 = plt.figure(1,figsize=(12,5));
ax1 = plt.subplot(1,1,1);
plt.axis( [mmin, mmax, 0, max(p)] );
plt.plot( m, p, "r-", lw=3);
plt.plot( m, q, "g-", lw=3);
plt.xlabel("m");
plt.ylabel("p and q");
plt.show();
print("Caption: Two Normal pdfs p(m) (red) and q(m) (green)");
# relative entropy S
r = (sigmamp**2)/(sigmamq**2);
Sanalytic = ((mbarp-mbarq)**2)/(2*sigmamq*sigmamq) + 0.5*(r-1.0-log(r));
Snumeric = Dm*np.sum(np.multiply(p,np.log(np.divide(p,q))));
print("S = %f (analytic) and %f (numeric)" % (Sanalytic, Snumeric) );
# relative entropy as a function of sigmamp
Nv=100;
sigmampv = gda_cvec(sigmamq*np.linspace(1.0,Nv,Nv)/Nv);
rv = np.power(sigmampv,2)/(sigmamq**2);
Sv = ((mbarp-mbarq)**2)/(2*sigmamq*sigmamq) + 0.5*(rv-1-np.log(rv));
fig1 = plt.figure(1,figsize=(12,5));
ax1 = plt.subplot(1,1,1);
plt.axis( [0, sigmamq, 0, np.max(Sv)] );
plt.plot( sigmampv, Sv, "k-", lw=3);
plt.plot( sigmamp, Sanalytic, "ro", lw=3);
plt.xlabel('sigmamp');
plt.ylabel('S')
plt.show();
print("Caption: Relative entropy of p(m) and q(m) as the");
print("sigma of p id varied. One point on curve (red circle)");
print("determined by an analytic method");
gdapy06_09
Caption: Two Normal pdfs p(m) (red) and q(m) (green) S = 1.129438 (analytic) and 1.129438 (numeric)
Caption: Relative entropy of p(m) and q(m) as the sigma of p id varied. One point on curve (red circle) determined by an analytic method
In [11]:
# gdapy06_10
# examples of probability density function p(d1,m1)
print("gdapy06_10");
# d1-axis
Nd1 = 51;
d1min = 0.0;
d1max = 5.0;
Dd1 = (d1max-d1min)/(Nd1-1);
d1 = gda_cvec(d1min + Dd1*np.linspace(0,Nd1-1,Nd1));
# m1-axis
Nm1 = 51;
m1min = 0.0;
m1max = 5.0;
Dm1 = (m1max-m1min)/(Nm1-1);
m1 = gda_cvec(m1min + Dm1*np.linspace(0,Nm1-1,Nm1));
# setup for pdf
P1=np.zeros((Nd1,Nm1));
mbar1 = gda_cvec(2.5, 2.5);
sd1 = 0.5;
sd2 = 1.0;
C1 = np.diag( gda_cvec(sd1**2, sd2**2).ravel() );
CI1 = la.inv(C1);
DC1 = la.det(C1);
# normalization
norm1 = (1.0/(2.0*pi)) * (1.0/sqrt(DC1));
# tabulate distribution
for i in range(Nd1):
for j in range(Nm1):
x1 = gda_cvec(m1[i,0], m1[j,0]) - mbar1;
r2 = np.matmul(x1.T,np.matmul(CI1,x1)); r2=r2[0,0];
P1[i,j] = norm1*exp( -0.5*r2 );
# plot pdf
gda_draw(' ', P1 );
print("Caption: Probability density function p(m,d)");
gdapy06_10
Caption: Probability density function p(m,d)
In [12]:
# gdapy06_11
# parameteric function passing thru distribution p(d1,m1)
print("gdapy06_11");
# d1-axis
Nd1 = 101;
d1min = 0.0;
d1max = 5.0;
Dd1 = (d1max-d1min)/(Nd1-1);
d1 = gda_cvec(d1min + Dd1*np.linspace(0,Nd1-1,Nd1));
# m1-axis
Nm1 = 101;
m1min = 0.0;
m1max = 5.0;
Dm1 = (m1max-m1min)/(Nm1-1);
m1 = gda_cvec(m1min + Dm1*np.linspace(0,Nm1-1,Nm1));
# setup for pdf
P1=np.zeros((Nd1,Nm1));
d1bar = 2.25;
m1bar = 2.08;
bar = gda_cvec(d1bar, m1bar);
sd1 = 0.5;
sm1 = 1.0;
C1 = np.diag( gda_cvec(sd1**2, sm1**2).ravel() );
CI1 = la.inv(C1);
DC1 = la.det(C1);
norm1 = (1.0/(2.0*pi)) * (1.0/sqrt(DC1));
# tablulate pdf
for i in range(Nm1):
for j in range(Nd1):
x1 = gda_cvec(d1[i,0], m1[j,0]) - bar;
r2 = np.matmul(x1.T,np.matmul(CI1,x1)); r2=r2[0,0];
P1[i,j] = norm1*exp( -0.5*r2 );
# s-axis for parametric curve
Ns = 51;
smin = 0.0;
smax = 5.0;
Ds = (smax-smin)/(Ns-1);
s = gda_cvec(smin + Ds*np.linspace(0,Ns-1,Ns));
# parameric curve
dp = 1.0+s-2.0*np.power(s/smax,2);
mp = np.copy(s);
# P on parameteric curve
ipd = (np.floor((dp-d1min)/Dd1)).astype(int);
ipm = (np.floor((mp-m1min)/Dm1)).astype(int);
# insure indices in range
k=np.where(ipd<0);
i=k[0];
if( not np.any(i) ):
ipd[i,0]=0;
k=np.where(ipd>=Nd1);
i=k[0];
if( not np.any(i) ):
ipd[i,0]=Nd1-1;
k=np.where(ipm<0);
i=k[0];
if( not np.any(i) ):
ipm[i,0]=0;
k=np.where(ipm>=Nm1);
i=k[0];
if( not np.any(i) ):
ipm[i,0]=Nm1-1;
Ps=np.zeros((Ns,1));
# evaluate P at indices
for i in range(Ns):
Ps[i,0] = P1[ipd[i,0], ipm[i,0]];
# maximum along curve
Pmax = np.max(Ps);
ismax = np.argmax(Ps);
d1smax = dp[ismax,0];
m1smax = mp[ismax,0];
fig1 = plt.figure(1,figsize=(12,5));
ax1=plt.subplot(1,1,1);
mycmap=matplotlib.colormaps['jet'];
plt.axis( [d1min, d1max, m1min, m1max] );
left=d1min; right=d1max;
top=m1max; bottom=m1min;
dmax=np.max(P1);
ax1.invert_yaxis();
plt.imshow(np.flipud(P1), cmap=mycmap, vmin=0.0, vmax=dmax, extent=(left,right,bottom,top) );
plt.colorbar();
plt.plot( m1bar, d1bar, "wo", lw=3 );
plt.plot( gda_cvec(m1bar, m1bar), gda_cvec(d1max, d1max-0.1), "w-", lw=3 );
plt.plot( gda_cvec(m1min, m1min+0.1), gda_cvec(d1bar, d1bar), "w-", lw=3 );
plt.plot( mp, dp, 'w-', lw=3 );
plt.plot( m1smax, d1smax, 'ko', lw=4);
plt.plot( gda_cvec(m1min, m1smax), gda_cvec(d1smax, d1smax), "w:", lw=2);
plt.plot( gda_cvec(m1smax, m1smax), gda_cvec(d1max, d1smax), "w:", lw=2);
plt.xlabel("m");
plt.ylabel("d");
plt.show();
print("Caption: Probability density function p(d,m) (colors) with parametric curve");
print("f(d,m)=0 (white) superimposed. The point of mximum probability");
print("along the curve is shown with a black circle.");
# plot pdf as a function of arclength along curve
fig1 = plt.figure(1,figsize=(12,5));
ax1=plt.subplot(1,1,1);
plt.axis( [smin, smax, 0, 0.3] );
plt.plot( s, Ps, "b-", lw=3 );
plt.xlabel("s");
plt.ylabel("p(s)");
plt.show();
print("Caption: Probability as a function of arc-length along the parametric curve.");
print("The probability has a single maximum.");
gdapy06_11
Caption: Probability density function p(d,m) (colors) with parametric curve f(d,m)=0 (white) superimposed. The point of mximum probability along the curve is shown with a black circle.
Caption: Probability as a function of arc-length along the parametric curve. The probability has a single maximum.
In [13]:
# gdapy06_12
# parameteric function passing thru distribution p(d1,m1)
print("gdapy06_12");
# d1-axis
Nd1 = 101;
d1min = 0.0;
d1max = 5.0;
Dd1 = (d1max-d1min)/(Nd1-1);
d1 = gda_cvec(d1min + Dd1*np.linspace(0,Nd1-1,Nd1));
# m1-axis
Nm1 = 101;
m1min = 0.0;
m1max = 5.0;
Dm1 = (m1max-m1min)/(Nm1-1);
m1 = gda_cvec(m1min + Dm1*np.linspace(0,Nm1-1,Nm1));
# setup for pdf
P1=np.zeros((Nd1,Nm1));
d1bar = 2.25;
m1bar = 2.08;
bar = gda_cvec(d1bar, m1bar);
sd1 = 1;
sm1 = 0.2;
C1 = np.diag( gda_cvec(sd1**2, sm1**2).ravel() );
CI1 = la.inv(C1);
DC1 = la.det(C1);
norm1 = (1.0/(2.0*pi)) * (1.0/sqrt(DC1));
# tablulate pdf
for i in range(Nm1):
for j in range(Nd1):
x1 = gda_cvec(d1[i,0], m1[j,0]) - bar;
r2 = np.matmul(x1.T,np.matmul(CI1,x1)); r2=r2[0,0];
P1[i,j] = norm1*exp( -0.5*r2 );
# s-axis for parametric curve
Ns = 51;
smin = 0.0;
smax = 5.0;
Ds = (smax-smin)/(Ns-1);
s = gda_cvec(smin + Ds*np.linspace(0,Ns-1,Ns));
# parameric curve
dp = 1.0+s-2.0*np.power(s/smax,2);
mp = np.copy(s);
# P on parameteric curve
ipd = (np.floor((dp-d1min)/Dd1)).astype(int);
ipm = (np.floor((mp-m1min)/Dm1)).astype(int);
# insure indices in range
k=np.where(ipd<0);
i=k[0];
if( not np.any(i) ):
ipd[i,0]=0;
k=np.where(ipd>=Nd1);
i=k[0];
if( not np.any(i) ):
ipd[i,0]=Nd1-1;
k=np.where(ipm<0);
i=k[0];
if( not np.any(i) ):
ipm[i,0]=0;
k=np.where(ipm>=Nm1);
i=k[0];
if( not np.any(i) ):
ipm[i,0]=Nm1-1;
Ps=np.zeros((Ns,1));
# evaluate P at indices
for i in range(Ns):
Ps[i,0] = P1[ipd[i,0], ipm[i,0]];
# maximum along curve
Pmax = np.max(Ps);
ismax = np.argmax(Ps);
d1smax = dp[ismax,0];
m1smax = mp[ismax,0];
fig1 = plt.figure(1,figsize=(12,5));
ax1=plt.subplot(1,1,1);
mycmap=matplotlib.colormaps['jet'];
plt.axis( [d1min, d1max, m1min, m1max] );
left=d1min; right=d1max;
top=m1max; bottom=m1min;
dmax=np.max(P1);
ax1.invert_yaxis();
plt.imshow(np.flipud(P1), cmap=mycmap, vmin=0.0, vmax=dmax, extent=(left,right,bottom,top) );
plt.colorbar();
plt.plot( m1bar, d1bar, "wo", lw=3 );
plt.plot( gda_cvec(m1bar, m1bar), gda_cvec(d1max, d1max-0.1), "w-", lw=3 );
plt.plot( gda_cvec(m1min, m1min+0.1), gda_cvec(d1bar, d1bar), "w-", lw=3 );
plt.plot( mp, dp, 'w-', lw=3 );
plt.plot( m1smax, d1smax, 'ko', lw=4);
plt.plot( gda_cvec(m1min, m1smax), gda_cvec(d1smax, d1smax), "w:", lw=2);
plt.plot( gda_cvec(m1smax, m1smax), gda_cvec(d1max, d1smax), "w:", lw=2);
plt.xlabel("m");
plt.ylabel("d");
plt.show();
print("Caption: Probability density function p(d,m) (colors) with parametric curve");
print("f(d,m)=0 (white) superimposed. In this case the prior model is very certain");
print("The point of mximum probability along the curve is shown with a black circle.");
# plot pdf as a function of arclength along curve
fig1 = plt.figure(1,figsize=(12,5));
ax1=plt.subplot(1,1,1);
plt.axis( [smin, smax, 0.0, 1.0] );
plt.plot( s, Ps, "b-", lw=3 );
plt.xlabel("s");
plt.ylabel("p(s)");
plt.show();
print("Caption: Probability as a function of arc-length along the parametric curve.");
print("The probability has a single maximum.");
gdapy06_12
Caption: Probability density function p(d,m) (colors) with parametric curve f(d,m)=0 (white) superimposed. In this case the prior model is very certain The point of mximum probability along the curve is shown with a black circle.
Caption: Probability as a function of arc-length along the parametric curve. The probability has a single maximum.
In [14]:
# gdapy06_13
# parameteric function passing thru distribution p(d1,m1)
print("gdapy06_13");
# d1-axis
Nd1 = 101;
d1min = 0.0;
d1max = 5.0;
Dd1 = (d1max-d1min)/(Nd1-1);
d1 = gda_cvec(d1min + Dd1*np.linspace(0,Nd1-1,Nd1));
# m1-axis
Nm1 = 101;
m1min = 0.0;
m1max = 5.0;
Dm1 = (m1max-m1min)/(Nm1-1);
m1 = gda_cvec(m1min + Dm1*np.linspace(0,Nm1-1,Nm1));
# setup for pdf
P1=np.zeros((Nd1,Nm1));
d1bar = 2.25;
m1bar = 2.08;
bar = gda_cvec(d1bar, m1bar);
sd1 = 0.2;
sm1 = 1.0;
C1 = np.diag( gda_cvec(sd1**2, sm1**2).ravel() );
CI1 = la.inv(C1);
DC1 = la.det(C1);
norm1 = (1.0/(2.0*pi)) * (1.0/sqrt(DC1));
# tablulate pdf
for i in range(Nm1):
for j in range(Nd1):
x1 = gda_cvec(d1[i,0], m1[j,0]) - bar;
r2 = np.matmul(x1.T,np.matmul(CI1,x1)); r2=r2[0,0];
P1[i,j] = norm1*exp( -0.5*r2 );
# s-axis for parametric curve
Ns = 51;
smin = 0.0;
smax = 5.0;
Ds = (smax-smin)/(Ns-1);
s = gda_cvec(smin + Ds*np.linspace(0,Ns-1,Ns));
# parameric curve
dp = 1.0+s-2.0*np.power(s/smax,2);
mp = np.copy(s);
# P on parameteric curve
ipd = (np.floor((dp-d1min)/Dd1)).astype(int);
ipm = (np.floor((mp-m1min)/Dm1)).astype(int);
# insure indices in range
k=np.where(ipd<0);
i=k[0];
if( not np.any(i) ):
ipd[i,0]=0;
k=np.where(ipd>=Nd1);
i=k[0];
if( not np.any(i) ):
ipd[i,0]=Nd1-1;
k=np.where(ipm<0);
i=k[0];
if( not np.any(i) ):
ipm[i,0]=0;
k=np.where(ipm>=Nm1);
i=k[0];
if( not np.any(i) ):
ipm[i,0]=Nm1-1;
Ps=np.zeros((Ns,1));
# evaluate P at indices
for i in range(Ns):
Ps[i,0] = P1[ipd[i,0], ipm[i,0]];
# maximum along curve
Pmax = np.max(Ps);
ismax = np.argmax(Ps);
d1smax = dp[ismax,0];
m1smax = mp[ismax,0];
fig1 = plt.figure(1,figsize=(12,5));
ax1=plt.subplot(1,1,1);
mycmap=matplotlib.colormaps['jet'];
plt.axis( [d1min, d1max, m1min, m1max] );
left=d1min; right=d1max;
top=m1max; bottom=m1min;
dmax=np.max(P1);
ax1.invert_yaxis();
plt.imshow(np.flipud(P1), cmap=mycmap, vmin=0.0, vmax=dmax, extent=(left,right,bottom,top) );
plt.colorbar();
plt.plot( m1bar, d1bar, "wo", lw=3 );
plt.plot( gda_cvec(m1bar, m1bar), gda_cvec(d1max, d1max-0.1), "w-", lw=3 );
plt.plot( gda_cvec(m1min, m1min+0.1), gda_cvec(d1bar, d1bar), "w-", lw=3 );
plt.plot( mp, dp, 'w-', lw=3 );
plt.plot( m1smax, d1smax, 'ko', lw=4);
plt.plot( gda_cvec(m1min, m1smax), gda_cvec(d1smax, d1smax), "w:", lw=2);
plt.plot( gda_cvec(m1smax, m1smax), gda_cvec(d1max, d1smax), "w:", lw=2);
plt.xlabel("m");
plt.ylabel("d");
plt.show();
print("Caption: Probability density function p(d,m) (colors) with parametric curve");
print("f(d,m)=0 (white) superimposed. In this case the prior model is very certain");
print("The point of mximum probability along the curve is shown with a black circle.");
# plot pdf as a function of arclength along curve
fig1 = plt.figure(1,figsize=(12,5));
ax1=plt.subplot(1,1,1);
plt.axis( [smin, smax, 0.0, 1.0] );
plt.plot( s, Ps, "b-", lw=3 );
plt.xlabel("s");
plt.ylabel("p(s)");
plt.show();
print("Caption: Probability as a function of arc-length along the parametric curve.");
print("The probability has a single maximum.");
gdapy06_13
Caption: Probability density function p(d,m) (colors) with parametric curve f(d,m)=0 (white) superimposed. In this case the prior model is very certain The point of mximum probability along the curve is shown with a black circle.
Caption: Probability as a function of arc-length along the parametric curve. The probability has a single maximum.
In [15]:
# gdapy06_14
# prior distribution pA(d1,m1) interacting with inexact
# theory pg(d1,m1) to produce total distribution pT(d1,m1)
print("gdapy06_14");
# d1-axis
Nd1 = 101;
d1min = 0.0;
d1max = 5.0;
Dd1 = (d1max-d1min)/(Nd1-1);
d1 = gda_cvec(d1min + Dd1*np.linspace(0,Nd1-1,Nd1));
# m1-axis
Nm1 = 101;
m1min = 0;
m1max = 5.0;
Dm1 = (m1max-m1min)/(Nm1-1);
m1 = gda_cvec( m1min + Dm1*np.linspace(0,Nm1-1,Nm1));
# setup for distribution P1=PA
P1=np.zeros((Nd1,Nm1));
d1bar = 2.25;
m1bar = 2.08;
bar = gda_cvec(d1bar, m1bar);
sd1 = 0.5;
sm1 = 1.0;
C1 = np.diag( gda_cvec(sd1**2, sm1**2).ravel() );
CI1 = la.inv(C1);
DC1 = la.det(C1);
# note not normaalized, so max is unity
for i in range(Nm1):
for j in range(Nd1):
x1 = gda_cvec(d1[i,0], m1[j,0]) - bar;
r2 = np.matmul(x1.T,np.matmul(CI1,x1)); r2=r2[0,0];
P1[i,j] = np.exp( -0.5*r2 );
# s-axis for parametric curve s
Ns = 51;
smin = 0.0;
smax = 5.0;
Ds = (smax-smin)/(Ns-1);
s = gda_cvec(smin + Ds*np.linspace(0,Ns-1,Ns));
# Pg follows parameric curve
dp = 1.0+s-2.0*np.power(s/smax,2);
mp = np.copy(s);
# P2=Pg distribution; not normalizable
P2 = np.zeros((Nd1,Nm1));
sg1 = 0.35;
sg2 = sg1**2;
for i in range(Nm1):
for j in range(Nd1):
r2 = np.power(d1[i,0]-dp,2) + np.power(m1[j,0]-mp,2);
r2min=np.min(r2);
P2[i,j] = exp(-r2min/sg2);
# P3=PT is product of PA and Pg
P3 = np.multiply(P1,P2);
# find max
Pi, Pj, P3max = gda_matrixmin(P3)
Pmaxm1 = m1min+Dm1*Pj;
Pmaxd1 = d1min+Dd1*Pi;
fig1 = plt.figure(1,figsize=(12,5));
# plot PA
ax1=plt.subplot(1,3,1);
mycmap=matplotlib.colormaps['jet'];
plt.axis( [d1min, d1max, m1min, m1max] );
left=d1min; right=d1max;
top=m1max; bottom=m1min;
dmax=np.max(P1);
ax1.invert_yaxis();
plt.imshow(np.flipud(P1), cmap=mycmap, vmin=0.0, vmax=dmax, extent=(left,right,bottom,top) );
plt.colorbar(shrink=0.5);
plt.plot( m1bar, d1bar, "wo", lw=3 );
plt.plot( gda_cvec(m1bar, m1bar), gda_cvec(d1max, d1max-0.1), "w-", lw=3 );
plt.plot( gda_cvec(m1min, m1min+0.1), gda_cvec(d1bar, d1bar), "w-", lw=3 );
plt.plot( mp, dp, "w:", lw=2 );
plt.xlabel("m");
plt.ylabel("d");
# plot Pg
ax1=plt.subplot(1,3,2);
mycmap=matplotlib.colormaps['jet'];
plt.axis( [d1min, d1max, m1min, m1max] );
left=d1min; right=d1max;
top=m1max; bottom=m1min;
dmax=np.max(P2);
ax1.invert_yaxis();
plt.imshow(np.flipud(P2), cmap=mycmap, vmin=0.0, vmax=dmax, extent=(left,right,bottom,top) );
plt.colorbar(shrink=0.5);
plt.plot( m1bar, d1bar, "wo", lw=3 );
plt.plot( gda_cvec(m1bar, m1bar), gda_cvec(d1max, d1max-0.1), "w-", lw=3 );
plt.plot( gda_cvec(m1min, m1min+0.1), gda_cvec(d1bar, d1bar), "w-", lw=3 );
plt.plot( mp, dp, "w:", lw=2 );
plt.xlabel("m");
plt.ylabel("d");
# plot PT
ax1=plt.subplot(1,3,3);
mycmap=matplotlib.colormaps['jet'];
plt.axis( [d1min, d1max, m1min, m1max] );
left=d1min; right=d1max;
top=m1max; bottom=m1min;
dmax=np.max(P3);
ax1.invert_yaxis();
plt.imshow(np.flipud(P3), cmap=mycmap, vmin=0.0, vmax=dmax, extent=(left,right,bottom,top) );
plt.colorbar(shrink=0.5);
plt.plot( m1bar, d1bar, "wo", lw=3 );
plt.plot( gda_cvec(m1bar, m1bar), gda_cvec(d1max, d1max-0.1), "w-", lw=3 );
plt.plot( gda_cvec(m1min, m1min+0.1), gda_cvec(d1bar, d1bar), "w-", lw=3 );
plt.plot( mp, dp, "w:", lw=2 );
plt.xlabel("m");
plt.ylabel("d");
plt.show();
print("Caption: (Left) The prior pdf pA combining observation and prior information");
print("(Middle) the pdf of the theory Pg (right) the combined pdf pT");
gdapy06_14
Caption: (Left) The prior pdf pA combining observation and prior information (Middle) the pdf of the theory Pg (right) the combined pdf pT
In [16]:
# gdapy06_15
# Two different cases of:
#
# prior distribution pA(d1,m1) interacting with inexact
# theory pg(d1,m1) to produce total distribution pT(d1,m1)
#
# once case with very exact theory, other with very inexact one
print("gdapy06_15");
# d1-axis
Nd1 = 101;
d1min = 0.0;
d1max = 5.0;
Dd1 = (d1max-d1min)/(Nd1-1);
d1 = gda_cvec(d1min + Dd1*np.linspace(0,Nd1-1,Nd1));
# m1-axis
Nm1 = 101;
m1min = 0;
m1max = 5.0;
Dm1 = (m1max-m1min)/(Nm1-1);
m1 = gda_cvec( m1min + Dm1*np.linspace(0,Nm1-1,Nm1));
# Case 1: nearly exact theory
# setup for distribution P1=PA
P1=np.zeros((Nd1,Nm1));
d1bar = 2.25;
m1bar = 2.08;
bar = gda_cvec(d1bar, m1bar);
sd1 = 0.5;
sm1 = 1.0;
C1 = np.diag( gda_cvec(sd1**2, sm1**2).ravel() );
CI1 = la.inv(C1);
DC1 = la.det(C1);
# note not normaalized, so max is unity
for i in range(Nm1):
for j in range(Nd1):
x1 = gda_cvec(d1[i,0], m1[j,0]) - bar;
r2 = np.matmul(x1.T,np.matmul(CI1,x1)); r2=r2[0,0];
P1[i,j] = np.exp( -0.5*r2 );
# s-axis for parametric curve s
Ns = 51;
smin = 0.0;
smax = 5.0;
Ds = (smax-smin)/(Ns-1);
s = gda_cvec(smin + Ds*np.linspace(0,Ns-1,Ns));
# Pg follows parameric curve
dp = 1.0+s-2.0*np.power(s/smax,2);
mp = np.copy(s);
# P2=Pg distribution; not normalizable
P2 = np.zeros((Nd1,Nm1));
sg1 = 0.1;
sg2 = sg1**2;
for i in range(Nm1):
for j in range(Nd1):
r2 = np.power(d1[i,0]-dp,2) + np.power(m1[j,0]-mp,2);
r2min=np.min(r2);
P2[i,j] = exp(-r2min/sg2);
# P3=PT is product of PA and Pg
P3 = np.multiply(P1,P2);
# find max
Pi, Pj, P3max = gda_matrixmin(P3)
Pmaxm1 = m1min+Dm1*Pj;
Pmaxd1 = d1min+Dd1*Pi;
fig1 = plt.figure(1,figsize=(12,5));
# plot PA
ax1=plt.subplot(1,3,1);
mycmap=matplotlib.colormaps['jet'];
plt.axis( [d1min, d1max, m1min, m1max] );
left=d1min; right=d1max;
top=m1max; bottom=m1min;
dmax=np.max(P1);
ax1.invert_yaxis();
plt.imshow(np.flipud(P1), cmap=mycmap, vmin=0.0, vmax=dmax, extent=(left,right,bottom,top) );
plt.colorbar(shrink=0.5);
plt.plot( m1bar, d1bar, "wo", lw=3 );
plt.plot( gda_cvec(m1bar, m1bar), gda_cvec(d1max, d1max-0.1), "w-", lw=3 );
plt.plot( gda_cvec(m1min, m1min+0.1), gda_cvec(d1bar, d1bar), "w-", lw=3 );
plt.plot( mp, dp, "w:", lw=2 );
plt.xlabel("m");
plt.ylabel("d");
# plot Pg
ax1=plt.subplot(1,3,2);
mycmap=matplotlib.colormaps['jet'];
plt.axis( [d1min, d1max, m1min, m1max] );
left=d1min; right=d1max;
top=m1max; bottom=m1min;
dmax=np.max(P2);
ax1.invert_yaxis();
plt.imshow(np.flipud(P2), cmap=mycmap, vmin=0.0, vmax=dmax, extent=(left,right,bottom,top) );
plt.colorbar(shrink=0.5);
plt.plot( m1bar, d1bar, "wo", lw=3 );
plt.plot( gda_cvec(m1bar, m1bar), gda_cvec(d1max, d1max-0.1), "w-", lw=3 );
plt.plot( gda_cvec(m1min, m1min+0.1), gda_cvec(d1bar, d1bar), "w-", lw=3 );
plt.plot( mp, dp, "w:", lw=2 );
plt.xlabel("m");
plt.ylabel("d");
# plot PT
ax1=plt.subplot(1,3,3);
mycmap=matplotlib.colormaps['jet'];
plt.axis( [d1min, d1max, m1min, m1max] );
left=d1min; right=d1max;
top=m1max; bottom=m1min;
dmax=np.max(P3);
ax1.invert_yaxis();
plt.imshow(np.flipud(P3), cmap=mycmap, vmin=0.0, vmax=dmax, extent=(left,right,bottom,top) );
plt.colorbar(shrink=0.5);
plt.plot( m1bar, d1bar, "wo", lw=3 );
plt.plot( gda_cvec(m1bar, m1bar), gda_cvec(d1max, d1max-0.1), "w-", lw=3 );
plt.plot( gda_cvec(m1min, m1min+0.1), gda_cvec(d1bar, d1bar), "w-", lw=3 );
plt.plot( mp, dp, "w:", lw=2 );
plt.xlabel("m");
plt.ylabel("d");
plt.show();
print("Caption: Prior pdf pA(d1,m1) (left) interacting with");
print("inexact theory pg(d1,m1) (middle) to produce total pdf pT(d1,m1)");
print("(right). In this case, the theory is very exact.");
# Case 2: very inexact theory
# setup for distribution P1=PA
P1=np.zeros((Nd1,Nm1));
d1bar = 2.25;
m1bar = 2.08;
bar = gda_cvec(d1bar, m1bar);
sd1 = 0.5;
sm1 = 1.0;
C1 = np.diag( gda_cvec(sd1**2, sm1**2).ravel() );
CI1 = la.inv(C1);
DC1 = la.det(C1);
# note not normaalized, so max is unity
for i in range(Nm1):
for j in range(Nd1):
x1 = gda_cvec(d1[i,0], m1[j,0]) - bar;
r2 = np.matmul(x1.T,np.matmul(CI1,x1)); r2=r2[0,0];
P1[i,j] = np.exp( -0.5*r2 );
# s-axis for parametric curve s
Ns = 51;
smin = 0.0;
smax = 5.0;
Ds = (smax-smin)/(Ns-1);
s = gda_cvec(smin + Ds*np.linspace(0,Ns-1,Ns));
# Pg follows parameric curve
dp = 1.0+s-2.0*np.power(s/smax,2);
mp = np.copy(s);
# P2=Pg distribution; not normalizable
P2 = np.zeros((Nd1,Nm1));
sg1 = 2.0;
sg2 = sg1**2;
for i in range(Nm1):
for j in range(Nd1):
r2 = np.power(d1[i,0]-dp,2) + np.power(m1[j,0]-mp,2);
r2min=np.min(r2);
P2[i,j] = exp(-r2min/sg2);
# P3=PT is product of PA and Pg
P3 = np.multiply(P1,P2);
# find max
Pi, Pj, P3max = gda_matrixmin(P3)
Pmaxm1 = m1min+Dm1*Pj;
Pmaxd1 = d1min+Dd1*Pi;
fig1 = plt.figure(1,figsize=(12,5));
# plot PA
ax1=plt.subplot(1,3,1);
mycmap=matplotlib.colormaps['jet'];
plt.axis( [d1min, d1max, m1min, m1max] );
left=d1min; right=d1max;
top=m1max; bottom=m1min;
dmax=np.max(P1);
ax1.invert_yaxis();
plt.imshow(np.flipud(P1), cmap=mycmap, vmin=0.0, vmax=dmax, extent=(left,right,bottom,top) );
plt.colorbar(shrink=0.5);
plt.plot( m1bar, d1bar, "wo", lw=3 );
plt.plot( gda_cvec(m1bar, m1bar), gda_cvec(d1max, d1max-0.1), "w-", lw=3 );
plt.plot( gda_cvec(m1min, m1min+0.1), gda_cvec(d1bar, d1bar), "w-", lw=3 );
plt.plot( mp, dp, "w:", lw=2 );
plt.xlabel("m");
plt.ylabel("d");
# plot Pg
ax1=plt.subplot(1,3,2);
mycmap=matplotlib.colormaps['jet'];
plt.axis( [d1min, d1max, m1min, m1max] );
left=d1min; right=d1max;
top=m1max; bottom=m1min;
dmax=np.max(P2);
ax1.invert_yaxis();
plt.imshow(np.flipud(P2), cmap=mycmap, vmin=0.0, vmax=dmax, extent=(left,right,bottom,top) );
plt.colorbar(shrink=0.5);
plt.plot( m1bar, d1bar, "wo", lw=3 );
plt.plot( gda_cvec(m1bar, m1bar), gda_cvec(d1max, d1max-0.1), "w-", lw=3 );
plt.plot( gda_cvec(m1min, m1min+0.1), gda_cvec(d1bar, d1bar), "w-", lw=3 );
plt.plot( mp, dp, "w:", lw=2 );
plt.xlabel("m");
plt.ylabel("d");
# plot PT
ax1=plt.subplot(1,3,3);
mycmap=matplotlib.colormaps['jet'];
plt.axis( [d1min, d1max, m1min, m1max] );
left=d1min; right=d1max;
top=m1max; bottom=m1min;
dmax=np.max(P3);
ax1.invert_yaxis();
plt.imshow(np.flipud(P3), cmap=mycmap, vmin=0.0, vmax=dmax, extent=(left,right,bottom,top) );
plt.colorbar(shrink=0.5);
plt.plot( m1bar, d1bar, "wo", lw=3 );
plt.plot( gda_cvec(m1bar, m1bar), gda_cvec(d1max, d1max-0.1), "w-", lw=3 );
plt.plot( gda_cvec(m1min, m1min+0.1), gda_cvec(d1bar, d1bar), "w-", lw=3 );
plt.plot( mp, dp, "w:", lw=2 );
plt.xlabel("m");
plt.ylabel("d");
plt.show();
print("Caption: Prior pdf pA(d1,m1) (left) interacting with");
print("inexact theory pg(d1,m1) (middle) to produce total pdf pT(d1,m1)");
print("(right). In this case, the theory is very inexact");
gdapy06_15
Caption: Prior pdf pA(d1,m1) (left) interacting with inexact theory pg(d1,m1) (middle) to produce total pdf pT(d1,m1) (right). In this case, the theory is very exact.
Caption: Prior pdf pA(d1,m1) (left) interacting with inexact theory pg(d1,m1) (middle) to produce total pdf pT(d1,m1) (right). In this case, the theory is very inexact
In [17]:
# gdapy06_16
# total distribution pT(m1,d1) and the projected
# distribution p(m) = (integral) pT(m1,d1) d(d1)
# highlighting the possibility that the maximum
# liklihood points of the two distributions are
# at two different values of m1
print("gdapy06_16");
# d1-axis
Nd1 = 101;
d1min = 0.0;
d1max = 5.0;
Dd1 = (d1max-d1min)/(Nd1-1);
d1 = gda_cvec( d1min + Dd1*np.linspace(0,Nd1-1,Nd1));
# m1-axis
Nm1 = 101;
m1min = 0.0;
m1max = 5.0;
Dm1 = (m1max-m1min)/(Nm1-1);
m1 = gda_cvec(m1min + Dm1*np.linspace(0,Nm1-1,Nm1));
# distribution P1 = pA
P1=np.zeros((Nd1,Nm1));
d1bar = 2.25;
m1bar = 2.08;
bar = gda_cvec(d1bar, m1bar);
sd1 = 0.5;
sm1 = 1.0;
C1 = np.diag( gda_cvec(sd1**2, sm1**2).ravel() );
CI1 = la.inv(C1);
DC1 = la.det(C1);
# note not normaalized, so max is unity
for i in range(Nm1):
for j in range(Nd1):
x1 = gda_cvec( d1[i,0], m1[j,0] ) - bar;
r2 = np.matmul(x1.T,np.matmul(CI1,x1)); r2=r2[0,0];
P1[i,j] = exp( -0.5*r2 );
# s-axis for parametric curve
Ns = 51;
smin = 0.0;
smax = 5.0;
Ds = (smax-smin)/(Ns-1);
s = gda_cvec(smin + Ds*np.linspace(0,Ns-1,Ns));
# parameric curve
dp = 1.0+s-2.0*(s/smax)**2;
mp = np.copy(s);
# P2 = Pg
P2 = np.zeros((Nd1,Nm1));
sg1 = 0.35;
sg2 = sg1**2;
for i in range(Nm1):
for j in range(Nd1):
r2 = np.power(d1[i,0]-dp,2) + np.power(m1[j,0]-mp,2);
r2min=np.min(r2);
P2[i,j] = exp( -r2min/sg2 );
#P3 = pT with pT=pA pg
P3 = np.multiply(P1,P2);
# find maximum
Pi, Pj, P3max = gda_matrixmin(-P3);
P3max=-P3max;
Pmaxm1 = m1min+Dm1*Pj;
Pmaxd1 = d1min+Dd1*Pi;
# integrate over data
Pm = np.sum(P3,axis=0);
Pmmax = np.max(Pm);
Pmi = np.argmax(Pm);
Pmm = m1min+Dm1*Pmi;
norm=Dm1*np.sum(Pm);
Pm = Pm/norm;
# plot pT(d1,m1)
fig1 = plt.figure(1,figsize=(12,5));
ax1=plt.subplot(1,1,1);
mycmap=matplotlib.colormaps['jet'];
plt.axis( [d1min, d1max, m1min, m1max] );
left=d1min; right=d1max;
top=m1max; bottom=m1min;
dmax=np.max(P3);
ax1.invert_yaxis();
# for testing orientation
#P3=np.zeros((Nd1,Nm1)); id1=2; im1=2; P3[id1,im1]=dmax;
#P3=np.zeros((Nd1,Nm1)); id1=Nd1-2; im1=2; P3[id1,im1]=dmax;
#P3=np.zeros((Nd1,Nm1)); id1=2; im1=Nm1-2; P3[id1,im1]=dmax;
plt.imshow(np.flipud(P3), cmap=mycmap, vmin=0.0, vmax=dmax, extent=(left,right,bottom,top) );
plt.colorbar(shrink=0.5);
plt.plot( mp, dp, "w:", lw=2 );
plt.plot( m1bar, d1bar, "wo", lw=3 );
plt.plot( Pmaxm1, Pmaxd1, "ko", lw=3 );
plt.plot( gda_cvec(m1bar, m1bar), gda_cvec(d1max, d1max-0.1), "w-", lw=3 );
plt.plot( gda_cvec(m1min, m1min+0.1), gda_cvec(d1bar, d1bar), "w-", lw=3 );
plt.plot( gda_cvec(Pmaxm1, Pmaxm1), gda_cvec(d1max, d1max-0.1), "k-", lw=3 );
plt.plot( gda_cvec(m1min, m1min+0.1), gda_cvec(Pmaxd1, Pmaxd1), "k-", lw=3 );
plt.xlabel("m");
plt.ylabel("d");
plt.show();
print("Caption: Total pdf pT(d,m) with prior value (white circle), maximum");
print("likelihood point (black cirle), and theory (dashed line) superimposed.");
# plot p(m1)
fig2 = plt.figure(2,figsize=(12,5));
ax1=plt.subplot(1,1,1);
plt.axis( [m1min, m1max, 0, 1] );
plt.plot( m1, Pm, "b-", lw=3 );
plt.plot( Pmm, np.max(Pm), "ko", lw=3 );
plt.xlabel("m");
plt.ylabel("p(m)");
plt.show();
print("Caption: Projected pdf p(m)=(integral) pT(d,m) dd (blue curve) and");
print("maximum likelihood point (black cirle).");
gdapy06_16
Caption: Total pdf pT(d,m) with prior value (white circle), maximum likelihood point (black cirle), and theory (dashed line) superimposed.
Caption: Projected pdf p(m)=(integral) pT(d,m) dd (blue curve) and maximum likelihood point (black cirle).
In [18]:
# gdapy06_17
# sample chi-squared analysis
# distribution of errors P (Phi), E and L
# for a problem of a band-limited timeseries
# with redundant noisy observations of the
# time series and with a priori smoothness
# information
print("gdapy06_17");
# time t-axis
M=101;
Dt=1;
t = gda_cvec( Dt*np.linspace(0,M-1,M));
tmax = t[M-1,0];
# make a wiggly curve m(t) by starting out with random noise
# and bandpass filtering it around a narrow range of angular
# frquencies centered on w0. The bandpass filtering is
# accomplished by the gda_chebyshevfilt() function, which
# though not mentioned in the text (sorry about that) is pretty
# easy to use and has many other applications. Its arguments are
# output_timeseries = gda_chebyshevfilt( input_timeseries, Dt, f1, f2 )
# where Dt is the sampling of the timeseries (say in s) and
# (f1,f2) are the (low,high) size of the frequency band (say in Hz)
n = 10;
A = 2.0;
w0 = n*pi/tmax;
Dw = w0/10.0;
nse = np.random.normal(loc=0.0,scale=1.0,size=(M,1));
mtrue, uu, vv = gda_chebyshevfilt( nse, Dt, (w0-Dw)/(2*pi), (w0+Dw)/(2*pi) );
mtrue = A*mtrue/np.max(np.abs(mtrue));
# components of data kernel, all normalize to produce
# data of about the same value
# data kernel is just 3 independent observations of same point
N = 3*M;
G = np.concatenate((np.identity(M),np.identity(M),np.identity(M)),axis=0);
dtrue = np.matmul(G,mtrue);
sigma_d = 0.1;
dobs = dtrue + np.random.normal(loc=0.0,scale=sigma_d,size=(N,1));
sqrtcovdi = np.identity(N)/sigma_d;
# prior information: second derivative close to zero
tr = gda_cvec( 1.0, np.zeros((M-3,1)) );
tc = gda_cvec( 1.0, -2.0, 1.0, np.zeros((M-3,1)) );
H = (1.0/Dt**2)*la.toeplitz( tr.ravel(), tc.ravel() );
h = np.zeros((M-2,1));
K = M-2;
mddtrue = np.matmul(H,mtrue);
sigma_mdd = (w0**2)*A/sqrt(2.0);
sigma_mdd2 = np.std(mddtrue); # for test purposes
sqrtcovhi = np.identity(K)/sigma_mdd;
# generalized least squares equation and its solution
F = np.concatenate( (np.matmul(sqrtcovdi,G), np.matmul(sqrtcovhi,H)), axis=0 );
f = np.concatenate( (np.matmul(sqrtcovdi,dobs), np.matmul(sqrtcovhi,h)), axis=0);
FTF = np.matmul(F.T,F);
FTf = np.matmul(F.T,f);
mest = la.solve(FTF,FTf);
FTFinv = la.inv(FTF);
Cm = FTFinv;
mddest = np.matmul(H,mest);
sigma_mdd3 = np.std(mddest); # for test purposes
# plot m
fig1 = plt.figure(1,figsize=(12,5));
ax1=plt.subplot(1,1,1);
plt.axis( [0, tmax, -1.1*A, 1.1*A] );
plt.plot( t, dobs[0:M,0], "b.", lw=2 );
plt.plot( t, dobs[M:2*M,0], "b.", lw=2 );
plt.plot( t, dobs[2*M:3*M], "b.", lw=2 );
plt.plot( t, mtrue, "k-", lw=4 );
plt.plot( t, mest, "r-", lw=2 );
plt.xlabel("t (s)");
plt.ylabel("m");
plt.show();
print("Caption: Bandlimited time series, m(t). True (black)");
print("estimated (red), redundant observations (blue).");
# chi-squared values
e = np.matmul(sqrtcovdi,(np.matmul(G,mest)-dobs)); # normalized prediction error
l = np.matmul(sqrtcovhi,(np.matmul(H,mest)-h)); # normalized prior error
E = np.matmul(e.T,e); E=E[0,0]; # Eobs
L = np.matmul(l.T,l); L=L[0,0]; # Lobs
P = E+L; # PHIobs
vP = N+K-M; # degrees of freeedom in PHI
vE = vP*N/(N+K); # approx degrees of freeedom in E
vL = vP*K/(N+K); # approx degrees of freeedom in L
# Chi-squared test of the Null Hypothesis
print(" ");
print("Analytic 95% confidence tests");
if ( P>(vP-2.0*sqrt(2.0*vP)) and P<(vP+2.0*sqrt(2.0*vP)) ):
print("P %.2f vP %.2f null hypothesis cannot be rejected" % (P, vP) );
else:
print("P %.2f vP %.2f null hypothesis can be rejected" % (P, vP));
if ( E>(vE-2.0*sqrt(2.0*vE)) and E<(vE+2.0*sqrt(2.0*vE)) ):
print("E %.2f vE %.2f null hypothesis cannot be rejected" % (E, vE) );
else:
print("E %.2f vE %.2f null hypothesis can be rejected" % (E, vE) );
if ( L>(vL-2.0*sqrt(2.0*vL)) and L<(vL+2.0*sqrt(2.0*vL)) ):
print("L %.2f vL %.2f null hypothesis cannot be rejected" % (L, vL) );
else:
print("L %.2f vL %.2f null hypothesis can be rejected" % (L, vL) );
print(" ");
# Now do it lots of times to create empirical pdf's
# p(PHI), p(E) and p(L)
Nreal = 10000;
Pvec = np.zeros((Nreal,1));
Evec = np.zeros((Nreal,1));
Lvec = np.zeros((Nreal,1));
for ireal in range(Nreal):
dobs = dtrue + np.random.normal(loc=0.0,scale=sigma_d,size=(N,1));
f = np.concatenate( (np.matmul(sqrtcovdi,dobs), np.matmul(sqrtcovhi,h)), axis=0);
FTf = np.matmul(F.T,f);
mest = la.solve(FTF,FTf);
ei = np.matmul(sqrtcovdi,(np.matmul(G,mest)-dobs)); # normalized prediction error
li = np.matmul(sqrtcovhi,(np.matmul(H,mest)-h)); # normalized prior error
Ei = np.matmul(ei.T,ei); Ei=Ei[0,0]; # Eobs
Li = np.matmul(li.T,li); Li=Li[0,0]# Lobs
Evec[ireal,0] = Ei;
Lvec[ireal,0] = Li;
Pvec[ireal,0] = Ei+Li;
Evec = np.sort(Evec,axis=0);
Lvec = np.sort(Lvec,axis=0);
Pvec = np.sort(Pvec,axis=0);
# empirical pdf's via histograms
Nb=201;
binmin = 0;
binmax = 2*vP;
h, e = np.histogram(Pvec,Nb,(binmin,binmax)); # create histogram
Nbin = len(h); # lengths of histogram
Ne = len(e); # length of edges
edges = gda_cvec(e[0:Ne-1]); # convert e to column-vector
bins = edges + 0.5*(edges[1,0]-edges[0,0]); # centers of bins
Db = bins[1,0]-bins[0,0]; # size of bins
Phist = gda_cvec(h); # empirical pdf
h, e = np.histogram(Evec,Nb,(binmin,binmax)); # create histogram
Ehist = gda_cvec(h); # empirical pdf
h, e = np.histogram(Lvec,Nb,(binmin,binmax)); # create histogram
Lhist = gda_cvec(h); # empirical pdf
# p(P)
fig2 = plt.figure(2,figsize=(12,5));
ax1=plt.subplot(1,1,1);
top = 1.1*max(Phist);
plt.axis( [binmin, binmax, 0, top ] );
plt.plot( bins,Phist, "k-", lw=3 );
plt.plot( gda_cvec(vP, vP), gda_cvec(0, top/5), "r-", lw=2 );
plt.plot( gda_cvec(vP-2*sqrt(2*vP), vP-2*sqrt(2*vP)), gda_cvec(0.0, top/10), "b-", lw=4 );
plt.plot( gda_cvec(vP+2*sqrt(2*vP), vP+2*sqrt(2*vP)), gda_cvec(0.0, top/10), "b-", lw= 4 );
plt.xlabel("P");
plt.ylabel("counts");
plt.show();
# p(E)
fig3 = plt.figure(3,figsize=(12,5));
ax1=plt.subplot(1,1,1);
top = 1.1*max(Ehist);
plt.axis( [binmin, binmax, 0, top ] );
plt.plot( bins,Ehist, "k-", lw=3 );
plt.plot( gda_cvec(vE, vE), gda_cvec(0, top/5), "r-", lw=2 );
plt.plot( gda_cvec(vE-2*sqrt(2*vE), vE-2*sqrt(2*vE)), gda_cvec(0.0, top/10), "b-", lw=4 );
plt.plot( gda_cvec(vE+2*sqrt(2*vE), vE+2*sqrt(2*vE)), gda_cvec(0.0, top/10), "b-", lw= 4 );
plt.xlabel("E");
plt.ylabel("counts");
plt.show();
# p(L)
fig4 = plt.figure(4,figsize=(12,5));
ax1=plt.subplot(1,1,1);
top = 1.1*max(Lhist);
plt.axis( [binmin, binmax, 0, top ] );
plt.plot( bins,Lhist, "k-", lw=3 );
plt.plot( gda_cvec(vL, vL), gda_cvec(0, top/5), "r-", lw=2 );
plt.plot( gda_cvec(vL-2*sqrt(2*vL), vL-2*sqrt(2*vL)), gda_cvec(0.0, top/10), "b-", lw=4 );
plt.plot( gda_cvec(vL+2*sqrt(2*vL), vL+2*sqrt(2*vL)), gda_cvec(0.0, top/10), "b-", lw= 4 );
plt.xlabel("L");
plt.ylabel("counts");
plt.show();
print("Caption: Empirical pdfs for (top) generalized error Phi,");
print("(middle) prediction error E and (bottom) error in prior information");
print("Also shown are mean z(red) and 95 percent confidence bounds (blue).");
# empirical confidence limits based on the empirical pdf's
print(" ");
print("Numerical 95% confidence tests");
k=np.where(P<Pvec);
i=k[0];
if( not np.any(i) ):
p=0.0;
else:
p = float(i[0])/float(Nreal);
if ( p>0.025 and p<0.975):
print("P %.2f vP %.2f null hypothesis cannot be rejected" % (P, vP) );
else:
print("P %.2f vP %.2f null hypothesis can be rejected" % (P, vP) );
k=np.where(E<Evec);
i=k[0];
if( not np.any(i) ):
p=0.0;
else:
p = float(i[0])/float(Nreal);
if ( p>0.025 and p<0.975):
print("E %.2f vE %.2f null hypothesis cannot be rejected" % (E, vE) );
else:
print("E %.2f vE %.2f null hypothesis can be rejected" % (E, vE) );
k=np.where(L<Lvec);
i=k[0];
if( not np.any(i) ):
p=0.0;
else:
p = float(i[0])/float(Nreal);
if ( p>0.025 and p<0.975):
print("L %.2f vL %.2f null hypothesis cannot be rejected" % (L, vL) );
else:
print("L %.2f vL %.2f null hypothesis can be rejected" % (L, vL) );
gdapy06_17
Caption: Bandlimited time series, m(t). True (black) estimated (red), redundant observations (blue). Analytic 95% confidence tests P 314.01 vP 301.00 null hypothesis cannot be rejected E 227.54 vE 226.87 null hypothesis cannot be rejected L 86.47 vL 74.13 null hypothesis cannot be rejected
Caption: Empirical pdfs for (top) generalized error Phi, (middle) prediction error E and (bottom) error in prior information Also shown are mean z(red) and 95 percent confidence bounds (blue). Numerical 95% confidence tests P 314.01 vP 301.00 null hypothesis cannot be rejected E 227.54 vE 226.87 null hypothesis cannot be rejected L 86.47 vL 74.13 null hypothesis cannot be rejected
In [19]:
# gdapy06_18
# example F-test to assess difference in fit of two models
# the two models are linear and cubic fit of the same d(z)
# dataset
print("gdapy06_18");
# auxially variable z
N = 11;
z = gda_cvec(np.linspace(0.0,N-1,N)/(N-1));
dtrue = z - 0.5*np.power(z,2);
# simulated data
sigmad=0.03;
dobs = dtrue + np.random.normal(loc=0.0, scale=sigmad,size=(N, 1) );
fig1 = plt.figure(1,figsize=(12,5));
ax1=plt.subplot(1,1,1);
plt.axis( [0, 1, -1, 1] );
plt.plot(z,dobs,"ro",lw=3);
# plot the observed data
# fit 1, straight line
M=2;
G=np.concatenate((np.ones((N,1)), z), axis=1);
GTG = np.matmul(G.T,G);
GTd = np.matmul(G.T,dobs);
mestA=la.solve(GTG,GTd);
dpreA = np.matmul(G,mestA);
# plot the predicted data for the linear fit
plt.plot(z,dpreA,"b-",lw=3);
plt.title("linear fit");
plt.xlabel("z");
plt.ylabel("d(z)");
plt.show();
print("Caption: Linear fit (blue curve) to data (red circles).");
print(" ");
# linear error
EA = np.matmul((dobs-dpreA).T,dobs-dpreA); EA=EA[0,0];
vA = N-M; # degrees of freedom
print("linear error %f, degrees of freedom %d" % (EA, vA) );
# plot the observed data
fig2 = plt.figure(2,figsize=(12,5));
ax1=plt.subplot(1,1,1);
plt.axis( [0, 1, -1, 1] );
plt.plot(z,dobs,"ro",lw=3);
# fit 2, cubic
M=4;
G=np.concatenate((np.ones((N,1)),z,np.power(z,2),np.power(z,3)),axis=1);
GTG = np.matmul(G.T,G);
GTd = np.matmul(G.T,dobs);
mestB=la.solve(GTG,GTd);
dpreB = np.matmul(G,mestB);
# plot the predicted data for the cubic fit
plt.plot(z,dpreB,"b-",lw=3);
plt.title("cubic fit");
plt.xlabel("z");
plt.ylabel("d(z)");
plt.show();
print("Caption: Cubic fit (blue curve) to data (red circles)");
print(" ");
# error of cubic fit
EB = np.matmul((dobs-dpreB).T,dobs-dpreB); EB=EB[0,0];
vB = N-M; # degrees of freedom
print("cubic error %f, degrees of freedom %d" % (EB,vB) );
Fobs = (EA/vA) / (EB/vB); # F-value
print("1/F %f F %f" % (1.0/Fobs, Fobs));
# probability value associated with F-value
if( Fobs<1.0 ):
Fobs=1.0/Fobs;
P = 1.0 - (st.f.cdf(Fobs,vA,vB)-st.f.cdf(1.0/Fobs,vA,vB));
Pleft = st.f.cdf(1.0/Fobs,vA,vB);
Pright = 1.0-st.f.cdf(Fobs,vA,vB);
print("P(F<%f) = %f" % (1.0/Fobs, Pleft) );
print("P(F>%f) = %f" % (Fobs, Pright) );
print("P(F<%f or F>%f) = %f" % (1.0/Fobs, Fobs, P));
if( (Pleft+Pright)<0.05 ):
print("Null Hypothesis can be rejected to 95% confidence");
else:
print("Null Hypothesis cannot be rejected to 95% confidence");
gdapy06_18
Caption: Linear fit (blue curve) to data (red circles). linear error 0.025540, degrees of freedom 9
Caption: Cubic fit (blue curve) to data (red circles) cubic error 0.004077, degrees of freedom 7 1/F 0.205219 F 4.872853 P(F<0.205219) = 0.015787 P(F>4.872853) = 0.024329 P(F<0.205219 or F>4.872853) = 0.040116 Null Hypothesis can be rejected to 95% confidence
In [20]:
# gdapy06_19
# example of F test for problem with prior information
print("gdapy06_19");
# dense set of model parameters
M1=101; # must be odd
# densely sampled time t variable
Dt1=1.0;
t1 = gda_cvec(Dt1*np.linspace(0,M1-1,M1));
t1max=t1[M1-1,0];
# sparse set of model parameters
M2=int(floor((M1+1)/2));
# sparsely sampled time t variable
Dt2=2.0*Dt1;
t2 = gda_cvec(Dt2*np.linspace(0,M2-1,M2));
# matrix D2S takes dense to sparse model parameters by decimation
# m2 = D2S*m1
D2S = np.zeros((M2, M1));
j=0;
for i in range(M2):
D2S[i,j]=1.0;
j=j+2;
# matrix S2D takes sparse to dense model parameters by linear interpolation
# m1 = S2D*m2
S2D = np.zeros((M1, M2));
j=0;
for i in range(0,M1,2):
S2D[i,j]=1;
j=j+1;
j=0;
for i in range(1,M1-1,2):
S2D[i,j]=0.5;
S2D[i,j+1]=0.5;
j=j+1;
# make a densely sampled wiggly curve m(t) by starting out with random noise
# and bandpass filtering it around a narrow range of angular
# frquencies centered on w0. The bandpass filtering is
# accomplished by the gda_chebyshevfilt() function, which
# though not mentioned in the text (sorry about that) is pretty
# easy to use and has many other applications. Its arguments are
# output_timeseries = gda_chebyshevfilt( input_timeseries, Dt, f1, f2 )
# where Dt is the sampling of the timeseries (say in s) and
# (f1,f2) are the (low,high) size of the frequency band (say in Hz)
n = 10;
A = 2.0;
w0 = n*pi/t1max;
Dw = w0/10.0;
nse = np.random.normal(loc=0.0,scale=1.0,size=(M1,1));
mtrue1,uu,vv = gda_chebyshevfilt( nse, Dt1, (w0-Dw)/(2.0*pi), (w0+Dw)/(2.0*pi) );
mtrue1 = A*mtrue1/np.max(np.abs(mtrue1));
# data kernel is just 3 independent observations of same point
N = 3*M1;
G1 = np.concatenate((np.identity(M1),np.identity(M1),np.identity(M1)),axis=0);
G2 = np.concatenate((S2D, S2D, S2D), axis=0 );
dtrue = np.matmul(G1,mtrue1);
# observed data is noisy
sigma_d = 0.1;
dobs = dtrue + np.random.normal(loc=0.0,scale=sigma_d,size=(N,1));
sqrtcovdi = np.identity(N)/sigma_d;
# prior information: second derivative close to zero
K1 = M1-2;
tr = gda_cvec(1.0, np.zeros((M1-3,1)) );
tc = gda_cvec(1.0, -2.0, 1.0, np.zeros((M1-3)) );
H1 = (1.0/(Dt1**2))*la.toeplitz( tr.ravel(), tc.ravel() );
h1 = np.zeros((M1-2,1));
K2 = M2-2;
tr = gda_cvec( 1.0, np.zeros((M2-3,1)) );
tc = gda_cvec( 1.0, -2.0, 1.0, np.zeros((M2-3,1)) );
H2 = (1/(Dt2**2))*la.toeplitz( tr, tc );
h2 = np.zeros((M2-2,1));
# prior covariance of model parameters
sigma_mdd = (w0**2)*A/sqrt(2.0);
sqrtcovhi1 = np.identity(K1)/sigma_mdd;
sqrtcovhi2 = np.identity(K2)/sigma_mdd;
# overall least squares equation and its solution dense problem
F1=np.concatenate((np.matmul(sqrtcovdi,G1),np.matmul(sqrtcovhi1,H1)),axis=0);
f1=np.concatenate((np.matmul(sqrtcovdi,dobs),np.matmul(sqrtcovhi1,h1)),axis=0);
FTF1 = np.matmul(F1.T,F1);
FTf1 = np.matmul(F1.T,f1);
mest1 = la.solve(FTF1,FTf1);
# sparse problem
F2=np.concatenate((np.matmul(sqrtcovdi,G2),np.matmul(sqrtcovhi2,H2)),axis=0);
f2=np.concatenate((np.matmul(sqrtcovdi,dobs),np.matmul(sqrtcovhi2,h2)),axis=0);
FTF2 = np.matmul(F2.T,F2);
FTf2 = np.matmul(F2.T,f2);
mest2 = la.solve(FTF2,FTf2);
# plot m
fig1 = plt.figure(1,figsize=(12,5));
ax1=plt.subplot(1,1,1);
plt.axis( [0, t1max, -1.1*A, 1.1*A] );
plt.plot( t1, dobs[0:M1,0], "b.", lw=2 );
plt.plot( t1, dobs[M1:2*M1], "b.", lw=2 );
plt.plot( t1, dobs[2*M1:3*M1], "b.", lw=2 );
plt.plot( t1, mtrue1, "k-", lw=8 );
plt.plot( t1, mest1, "r-", lw=5 );
plt.plot( t2, mest2, "g-", lw=3 );
plt.xlabel("t (s)");
plt.ylabel("m");
plt.show();
print("Caption: Bandlimited time series, true (black), estimated");
print("sparse solution (red), estimated dense solution (green), data (blue dots)");
print(" ");
# error associated with dense problem
e1 = np.matmul(sqrtcovdi ,np.matmul(G1,mest1)-dobs);
l1 = np.matmul(sqrtcovhi1,np.matmul(H1,mest1)-h1);
E1 = np.matmul(e1.T,e1); E1=E1[0,0];
L1 = np.matmul(l1.T,l1); L1=L1[0,0];
P1 = E1+L1;
vP1 = N+K1-M1;
vE1 = vP1*N/(N+K1);
vL1 = vP1*K1/(N+K1);
print("Fit 1: E1 %f vE1 %d L1 %f vL1 %d" % (E1,vE1,L1,vL1) );
print("N %d K1 %d M1 %d" % (N,K1,M1) );
# error associated with sparse problem
e2 = np.matmul(sqrtcovdi, np.matmul(G2,mest2)-dobs);
l2 = np.matmul(sqrtcovhi2,np.matmul(H2,mest2)-h2);
E2 = np.matmul(e2.T,e2); E2=E2[0,0];
L2 = np.matmul(l2.T,l2); L2=L2[0,0];
P2 = E2+L2;
vP2 = N+K2-M2;
vE2 = vP2*N/(N+K2);
vL2 = vP2*K2/(N+K2);
print("Fit 2: E2 %f vE2 %d L2 %f vL2 %d" % (E2,vE2,L2,vL2) );
print("N %d K2 %d M2 %d" % (N,K2,M2) );
# F ratio
vA=vP1;
vB=vP2;
PhiA = P1;
PhiB = P2;
Fobs = (PhiA/vA) / (PhiB/vB);
if( Fobs<1.0 ):
Fobs=1.0/Fobs;
print("1/F %f F %f" % (1.0/Fobs, Fobs) );
Pval = 1.0 - abs(st.f.cdf(1.0/Fobs,vA,vB)-st.f.cdf(Fobs,vA,vB));
Pleft = st.f.cdf(1.0/Fobs,vA,vB);
Pright = 1.0-st.f.cdf(Fobs,vA,vB);
print("P(F<%f) = %f" % (1.0/Fobs, Pleft) );
print("P(F>%f) = %f" % (Fobs, Pright) );
print("P(F<%f or F>%f) = %f" % (1.0/Fobs, Fobs, Pval) );
if( (Pleft+Pright)<0.05 ):
print("Null Hypothesis can be rejected to 95% confidence");
else:
print("Null Hypothesis cannot be rejected to 95% confidence");
# now do a whole lot of the same problems
# with different realizations of observational noise
Nreal = 10000;
FFvec = np.zeros((Nreal,1));
for ireal in range(Nreal):
# add new noise to data
dobs = dtrue + np.random.normal(loc=0.0,scale=sigma_d,size=(N,1));
# dense problem
f1=np.concatenate((np.matmul(sqrtcovdi,dobs),np.matmul(sqrtcovhi1,h1)),axis=0);
FTf1 = np.matmul(F1.T,f1);
mest1 = la.solve(FTF1,FTf1);
e1 = np.matmul(sqrtcovdi, np.matmul(G1,mest1)-dobs);
l1 = np.matmul(sqrtcovhi1,np.matmul(H1,mest1)-h1);
PP1 = np.matmul(e1.T,e1)+np.matmul(l1.T,l1); PP1=PP1[0,0];
# add new noise to data
dobs = dtrue + np.random.normal(loc=0.0,scale=sigma_d,size=(N,1));
# sparse problem
f2=np.concatenate((np.matmul(sqrtcovdi,dobs),np.matmul(sqrtcovhi2,h2)),axis=0);
FTf2 = np.matmul(F2.T,f2);
mest2 = la.solve(FTF2,FTf2);
e2 = np.matmul(sqrtcovdi, np.matmul(G2,mest2)-dobs);
l2 = np.matmul(sqrtcovhi2,np.matmul(H2,mest2)-h2);
PP2 = np.matmul(e2.T,e2)+np.matmul(l2.T,l2); PP2=PP2[0,0];
# tabulate F ratio
FFvec[ireal,0] = (PP1/vP1) / (PP2/vP2);
FFvec = np.sort(FFvec);
FFmean = np.mean(FFvec);
# empirical pdf's via histograms
Nb=101;
binmin = 0.5;
binmax = 1.5;
h, e = np.histogram(FFvec,Nb,(binmin,binmax)); # create histogram
Nbin = len(h); # lengths of histogram
Ne = len(e); # length of edges
edges = gda_cvec(e[0:Ne-1]); # convert e to column-vector
bins = edges + 0.5*(edges[1,0]-edges[0,0]); # centers of bins
Db = bins[1,0]-bins[0,0]; # size of bins
FFhist = gda_cvec(h); # empirical pdf
FFhist = FFhist/(Db*np.sum(FFhist));
# plot pdf
fig1 = plt.figure(1,figsize=(12,5));
ax1=plt.subplot(1,1,1);
top = 1.1*np.max(FFhist);
plt.axis( [binmin, binmax, 0.0, top ] );
plt.plot( bins,FFhist, "k-", lw=3 );
plt.plot( bins,st.f.pdf(bins,vP1,vP2), "r-", lw=3 );
plt.plot( gda_cvec(Fobs,Fobs), gda_cvec(0, top/5), "k-", lw=4 );
plt.plot( gda_cvec(FFmean,FFmean), gda_cvec(0, top/5.0), "g-", lw=4 );
plt.plot( gda_cvec(st.f.ppf(0.5,vP1,vP2),st.f.ppf(0.5,vP1,vP2)),gda_cvec(0.0, top/5.0), "r-", lw=4 );
plt.plot( gda_cvec(st.f.ppf(0.025,vP1,vP2),st.f.ppf(0.025,vP1,vP2)), gda_cvec(0.0, top/8.0), "b-", lw=4 );
plt.plot( gda_cvec(st.f.ppf(0.975,vP1,vP2),st.f.ppf(0.975,vP1,vP2)), gda_cvec(0.0, top/8.0), "b-", lw=4 );
plt.xlabel("F");
plt.ylabel("p(F)");
plt.show();
print("Caption: Analytic pdf p(F) (red curve), empirical pdf (black curve)");
print("observed F (black bar), empirical mean (green bar), true mean (red bar)");
print("95 percent confidence (blue bars).");
gdapy06_19
Caption: Bandlimited time series, true (black), estimated sparse solution (red), estimated dense solution (green), data (blue dots) Fit 1: E1 219.345135 vE1 226 L1 86.133665 vL1 74 N 303 K1 99 M1 101 Fit 2: E2 275.286438 vE2 259 L2 35.663579 vL2 41 N 303 K2 49 M2 51 1/F 0.982405 F 1.017910 P(F<0.982405) = 0.438859 P(F>1.017910) = 0.438859 P(F<0.982405 or F>1.017910) = 0.877718 Null Hypothesis cannot be rejected to 95% confidence
Caption: Analytic pdf p(F) (red curve), empirical pdf (black curve) observed F (black bar), empirical mean (green bar), true mean (red bar) 95 percent confidence (blue bars).
In [ ]: