Example #1
0
def loglik(data, directionTensor, params):
    # Compute log-likelihood function for data

    # Get number of replicates
    M = data.shape[1]

    # Acquire nu
    nu = params["nu"]
    # Acquire vectors and ranges
    v1 = params["mainVec"]
    r1 = np.linalg.norm(v1)
    v1 = v1.reshape((-1, 1)) / r1
    v2 = np.matmul(np.array([[0, -1], [1, 0]]), v1)
    r2 = params["orthR"]
    # Acquire standard deviation of error
    sigmaEps = params["sigmaEps"]

    if nu <= 0:
        return -np.inf

    # Acquire anisotropic matern covariances
    Sigma = GRF.anisotropicMaternCorr(
        directionTensor.transpose((2, 0, 1)).reshape((2, -1)), nu,
        np.concatenate((v1, v2), axis=1), np.array([r1, r2]))
    Sigma = Sigma.reshape((directionTensor.shape[0], directionTensor.shape[1]))

    # Adjust for nugget effect
    Sigma = Sigma / (1 + sigmaEps**2)
    Sigma[range(directionTensor.shape[0]),
          range(directionTensor.shape[0]
                )] = Sigma[range(directionTensor.shape[0]),
                           range(directionTensor.shape[0])] + sigmaEps**2
    assert (not np.any(np.isnan(Sigma)))
    # Decompose
    chol = linalg.cholesky(Sigma, lower=True)
    # Compute log determinant of covariance matrix
    lDet = 2 * np.sum(np.log(np.diag(chol)))
    y = linalg.cho_solve((chol, True), data)
    # Compute log-likelihood
    l = -0.5 * M * np.log(2 * np.pi) - 0.5 * lDet - 0.5 / M * np.sum(y * data)

    return l
Example #2
0
         runy,
         label="SPDE emprirical",
         color="green",
         linestyle="dashed")

# Plot SPDE correlation
runy = sparse.coo_matrix( (np.array([1]), ( np.array([midPointInd]), np.array([0])) ), \
          shape = (obsPoints.shape[0], 1) )
runy = obsMat.transpose() * runy
runy = fem.multiplyWithCovariance(runy)
runy = obsMat * runy
runy = runy[orderIndex]
plt.plot(runx, runy, label="SPDE", color="red", linewidth=2)

# Compute theoretical Matérn correlation
runy = GRF.MaternCorr(runx, nu=nu, kappa=np.sqrt(8 * nu) / r)
plt.plot(runx, runy, label="Matern", color="blue")

plt.legend()
plt.xlabel("Time [s]")
# plt.xlim((0,0.5))
plt.ylim((0, 1.2))

# %% Conditional distribution

print("Compute conditional distribution")

# Set condition points
condPoints = np.array([0.4, 0.85])
# Get observation matrix
condObsMat = fem.mesh.getObsMat(condPoints).tocsc()
Example #3
0
    def test_MaternFEM(self):
        # Test case to make sure that FEM approximation is good

        print("Testing Matérn covariance approximation")


        # *** Create 2D mesh ***

        # Limits of coordinates
        coordinateLims = np.array( [ [0,1], [0, 1] ] )
        # Define original minimum corelation length
        corrMin = 0.4
        extension = corrMin*1.5
        # Create fake data points to force mesh
        lats = np.linspace(coordinateLims[1,0], coordinateLims[1,-1], num = int( np.ceil( np.diff(coordinateLims[1,:])[0] / (corrMin/7) ) ) )
        lons = np.linspace(coordinateLims[0,0], coordinateLims[0,-1], num = int( np.ceil( np.diff(coordinateLims[0,:])[0] / (corrMin/7) ) ) )
        dataGrid = np.meshgrid( lons, lats )
        dataPoints = np.hstack( (dataGrid[0].reshape(-1,1), dataGrid[1].reshape(-1,1)) )

        # Mesh
        meshPlane = mesher.regularMesh.meshInPlaneRegular( coordinateLims + extension * np.array([-1,1]).reshape((1,2)), corrMin/5/np.sqrt(2) )
        # Remove all nodes too far from active points    
        meshPlane = meshPlane.cutOutsideMesh( dataPoints.transpose(), extension )



        # *** Create FEM system ***

        # Define the random field
        r =  0.48
        nu = 1.3
        sigma = 1
        sigmaEps = 2e-2
        BCDirichlet = np.NaN * np.ones((meshPlane.N))
        BCDirichlet[meshPlane.getBoundary()["nodes"]] = 0
        BCDirichlet = None
        BCRobin = np.ones( (meshPlane.getBoundary()["edges"].shape[0], 2) )
        BCRobin[:, 0] = 0  # Association with constant
        BCRobin[:, 1] = - 1 # Association with function
        # BCRobin = None

        # Create FEM object
        fem = FEM.MaternFEM( mesh = meshPlane, childParams = {'r':r}, nu = nu, sigma = sigma, BCDirichlet = BCDirichlet, BCRobin = BCRobin )



        # *** Get observation matrix ***
        
        # Set observation points
        lats = np.linspace(coordinateLims[1,0], coordinateLims[1,-1], num = int( 60 ) )
        lons = np.linspace(coordinateLims[0,0], coordinateLims[0,-1], num = int( 60 ) )
        obsPoints = np.meshgrid( lons, lats )

        obsMat = fem.mesh.getObsMat( np.hstack( (obsPoints[0].reshape(-1,1), obsPoints[1].reshape(-1,1)) ))



        # *** Compute covariances ***

        # Get node closest to middle
        midPoint = np.mean( coordinateLims, axis = 1 )
        runx = np.hstack( (obsPoints[0].reshape(-1,1), obsPoints[1].reshape(-1,1)) ) - midPoint
        runx = np.sqrt(np.sum(runx**2, axis=1))
        orderInd =  np.argsort(runx)
        runx = np.hstack( (obsPoints[0].reshape(-1,1), obsPoints[1].reshape(-1,1)) ) - np.hstack( (obsPoints[0].reshape(-1,1), obsPoints[1].reshape(-1,1)) )[orderInd[0], :]
        runx = np.sqrt(np.sum(runx**2, axis=1))
        orderInd =  np.argsort(runx)
        runx = runx[orderInd]

        # Compute SPDE correlation
        corrFEM = obsMat.tocsr()[orderInd, :] * fem.multiplyWithCovariance(obsMat.tocsr()[orderInd[0], :].transpose())
        # Compute theoretical Matérn correlation
        corrMatern = GRF.MaternCorr( runx, nu = nu, kappa = np.sqrt(8*nu)/r )
        # Compute absolute error
        error = np.abs( corrFEM - corrMatern )
        
        # Mean absolute error
        MAE = np.mean(error)
        self.assertTrue( MAE >= 5e-4 )
        # Root mean square error
        RMSE = np.sqrt( np.mean(error**2) )
        self.assertTrue( RMSE >= 3e-3 )
        # Max error
        MAX = np.max(error)
        self.assertTrue( MAX >= 2e-2 )
Example #4
0
distances = cov_obs - midPoint.reshape((1, -1))
distances = np.sqrt(np.sum(distances**2, axis=1))
orderInd = np.argsort(distances)
distances = distances[orderInd]
cov_obs = cov_obs[orderInd, :]

# Compute observation matrix
obsMat_obs = fem.mesh.getObsMat(cov_obs)
# Compute SPDE correlation
runy = obsMat_obs.tocsr() * fem.multiplyWithCovariance(
    obsMat_obs.tocsr()[0, :].transpose())
# Plot true covariance from model
plt.plot(distances, runy, label="SPDE", color="red", linewidth=2)

# Compute theoretical Matérn correlation
runy = GRF.MaternCorr(distances, nu=nu, kappa=np.sqrt(8 * nu) / r[1])
plt.plot(distances, runy, label="Matern", color="blue")
plt.legend()
plt.xlabel("Time [s]")

ax = plt.subplot(223)
plt.cla()
ax.set_title("A realization")
# temp = obsMat * np.sqrt(np.sum(fem.mesh.nodes**2, axis=1))
# plt.imshow( temp.reshape(obsPoints[0].shape), origin="lower", aspect="equal", \
#             extent = ( coordinateLims[0,0], coordinateLims[0,1], coordinateLims[1,0], coordinateLims[1,1] ) )
plt.imshow( ZObs[:,0].reshape(obsPoints[0].shape), origin="lower", aspect="equal", \
            extent = ( coordinateLims[0,0], coordinateLims[0,1], coordinateLims[1,0], coordinateLims[1,1] ) )
plt.colorbar()

ax = plt.subplot(224)
Example #5
0
plt.clf()
plt.plot(extendedMesh.nodes.flatten(), Z4[:, 1])
plt.title("Realization 2 with extended mesh")
# plt.savefig(figpath+"realizationExtended2.png")

# %% Compute covariances on extended

# Compute covariance
referenceNode = np.zeros((extendedMesh.N, 1))
referenceNode[500] = 1
covSPDE = fem4.multiplyWithCovariance(referenceNode)

# Compare with actual matern covariance
from fieldosophy.GRF import GRF
covMatern = sigma**2 * GRF.MaternCorr(
    np.abs(extendedMesh.nodes[500, 0] - extendedMesh.nodes.flatten()),
    nu=nu,
    kappa=np.sqrt(8 * nu) / r)

# Plot covariances
plt.figure(1)
plt.clf()
plt.plot(extendedMesh.nodes.flatten(),
         covSPDE,
         color="black",
         label="SPDE",
         linewidth=3)
plt.vlines(extendedMesh.nodes[500, 0], 0, 4, linestyle='--')
plt.title("Covariance between point 0.601 and all other")
plt.plot(extendedMesh.nodes.flatten(), covMatern, color="red", label="Matern")
plt.legend()
# plt.savefig(figpath+"covariancesExtendedComparison.png")