Warehouse: A cache for Pnets or Pnodes

WarehouseR Documentation

A cache for Pnets or Pnodes

Description

A warehouse is an object which stores a collection of Pnodes or Pnets. When requested, it will supply the given object. If the object already exists, it is returned. If it does not yet exist, it is built using meta-data in the warehouse's manifest.

Usage

WarehouseSupply(warehouse, name, restoreOnly=FALSE)
## S4 method for signature 'ANY'
WarehouseSupply(warehouse, name, restoreOnly=FALSE)
WarehouseFetch(warehouse, name)
WarehouseMake(warehouse, name, restoreOnly=FALSE)
WarehouseFree(warehouse, name)
WarehouseSave(warehouse, obj)
ClearWarehouse(warehouse)
is.valid(warehouse,object)
is.PnetWarehouse(obj)
is.PnodeWarehouse(obj)

Arguments

warehouse

A warehouse object from which the object is to be created.

name

A character vector giving the name of the object. Note that for net warehouses, the key is usually has length one, but for node warehouses, this usuall has the form (model,node).

obj

An object whose type is to be determined, or a network to be saved.

object

An object to be tested to see if it a valid object from this warehouse.

restoreOnly

A logical value. If true, then WarehouseMake will restore an object from a file, if available, but will generate an error if the instruction file is not available.

Details

The warehouse is a combination of a cache and a factory. The idea is that when a Pnet or Pnode object is needed, it is requested from the corresponding warehouse. If the object exists, it is returned. If the object does not exist, then the information in the manifest (see WarehouseManifest() is used to create a new object. The key function is WarehouseSupply(warehouse,name); this function looks for an object corresponding to name in warehouse. If it exists, it is returned, if not a new one is created.

The generic functions WarehouseFetch(warehouse,name) and WarehouseMake(warehouse,name) implement the supply protocol. WarehouseFetch(warehouse,name) searches for an object corresponding to name in the warehouse and returns it if it exists or returns NULL if it does not. The generic function WarehouseMake(warehouse,name) creates the object using the data in the manifest.

The function WarehouseSave saves the object back out to long term storage. This is particularly used for networks which are often prebuilt and then loaded when needed. Setting the argument restoreOnly=TRUE in WarehouseMake or WarehouseSupply will recreate an object from a save, but not create a new object.

The WarehouseFree and WarehouseClear functions complete the Warehouse prototocl. These respectively remove the named object from the cache, and clear the cache. Note that these may our may not make sense with the implementation. (In the current PNetica-package implementation, the cache is maintained by the underlying RNetica objects, and hence it doesn't make sense to free an object without deleting it.)

Each warehouse has a manifest which supplies the necessary data to build a praticular object. The generic function WarehouseManifest() accesses the manifest, which generally takes the form of a data.frame object. The functions BuildNetManifest() and BuildNodeManifest() build manifests for network and node objects respectively. The generic function WarehouseData(warehouse,name) returns the rows of the manifest which correspond to a paraticular name.

The Peanut package is concerned with two kinds of warehouses: Pnet warehouses and Pnode warehouses. Pnet warehouses contain Pnets, and the key is the name of the network. Each Pnet corresponds to a single line in the manifest, and the name is a character scalar. A Pnet warehouse should return true when the generic function is.PnetWarehouse() is called.

Pnode warehouses contain Pnodes, and the name is a character vector of length 2, with structure (netname, nodename). This is because nodes with the same name will frequently exist in two different networks. Currently the manifest for a node contains one line for each possible state of the node. A Pnode warehouse should return true when the generic function is.PnodeWarehouse() is called.

The function is.valid checks to see if the object is of a type mananged by the warehouse, and that it has valid data. In particular, the RNetica package uses pointers to objects in Netica space (as might other implementations). The is.valid() function checks that the current Pnet and Pnode object point to valid objects in the external heap if this is applicable to the application.

The warehouse object is an abstract class, and implementing classes need to provide methods for the generic functions WarehouseFetch(), WarehouseMake(), WarehouseFree(), WarehouseData(), WarehouseManifest(), WarehouseCopy(), is.legal.name(),as.legal.name(), is.valid() and ClearWarehouse() as well as one of the generic functions is.PnetWarehouse or is.PnodeWarehouse.

There are two reference implementations in BNWarehouse and NNWarehouse (network and node warehouses respectively). Both of these take advantage of the fact that the session and network objects in RNetica have built in environments which cache the networks and nodes respectively. The RGAutils::Warehouse-class object is a generic implementation that also may be of some use to potential implementors.

Value

The return type of most functions will depend on the type of the warehouse. In most cases, the functions return an object of the type of the warehouse.

Pnet Warehouses

These return TRUE from the function is.PnetWarehouse(), and an object of type Pnet or NULL from the functions WarehouseSupply(), WarehouseFetch(), and WarehouseMake(). NULL is returned when the requested net is not in the warehouse or the manifest.

Pnode Warehouses

These return TRUE from the function is.PnodeWarehouse(), and an object of type Pnode or NULL from the functions WarehouseSupply(), WarehouseFetch(), and WarehouseMake(). NULL is returned when the requested net is not in the warehouse or the manifest.

The returns from the functions WarehouseFree() and ClearWarehouse() are arbitrary depending on the implementation.

Note

There seem to be two use cases for WarehouseMake and WarehouseSupply when working with networks. During model construction, calling this function should create a new blank network. During scoring, it should load a prebuilt network and signal an error if the network is missing. The restoreOnly flag is designed to distinguish between these cases.

Note

The cache part of the warehouse, almost certainly needs to be implemented using the reference class system of Chambers (2016). In particular, an environment object provides the kind of persistent storage and object persistance and uniqueness necessary (this breaks the usual functional programming paradigm of R).

Author(s)

Russell G. Almond

References

Almond, R. G. (presented 2017, August). Tabular views of Bayesian networks. In John-Mark Agosta and Tomas Singlair (Chair), Bayeisan Modeling Application Workshop 2017. Symposium conducted at the meeting of Association for Uncertainty in Artificial Intelligence, Sydney, Australia. (International) Retrieved from http://bmaw2017.azurewebsites.net/

Chambers, J. M. (2016) Extending R. CRC Press.

See Also

Other warehouse functions: WarehouseCopy, is.legal.name

These functions support the manifest process. WarehouseManifest(), WarehouseData()

These functions construct manifests: BuildNetManifest(), BuildNodeManifest()

These functions use the warehouse to build networks: Omega2Pnet Qmat2Pnet

Examples


## Not run: 
## Requires PNetica package
library(PNetica)
sess <- NeticaSession()
startSession(sess)

### This tests the manifest and factory protocols.

netman1 <- read.csv(system.file("auxdata", "Mini-PP-Nets.csv", 
                                package="PNetica"),
                    row.names=1,stringsAsFactors=FALSE)

nodeman1 <- read.csv(system.file("auxdata", "Mini-PP-Nodes.csv", 
                                package="PNetica"),
                     stringsAsFactors=FALSE)

### Test Net building
Nethouse <- BNWarehouse(manifest=netman1,session=sess,key="Name")
stopifnot(is.PnetWarehouse(Nethouse))

curd <- setwd(system.file("testnets",package="PNetica"))
CM <- WarehouseSupply(Nethouse,"miniPP_CM")
stopifnot(is.null(WarehouseFetch(Nethouse,"PPcompEM")))
EM1 <- WarehouseMake(Nethouse,"PPcompEM")

EMs <- lapply(c("PPcompEM","PPconjEM", "PPtwostepEM", "PPdurAttEM"),
              function(nm) WarehouseSupply(Nethouse,nm))

### Test Node Building with already loaded nets

Nodehouse <- NNWarehouse(manifest=nodeman1,
                         key=c("Model","NodeName"),
                         session=sess)
stopifnot(is.PnodeWarehouse(Nodehouse))

phyd <- WarehouseData(Nodehouse,c("miniPP_CM","Physics"))

p3 <- MakePnode.NeticaNode(CM,"Physics",phyd)

phys <- WarehouseSupply(Nodehouse,c("miniPP_CM","Physics"))
stopifnot(p3==phys)

for (n in 1:nrow(nodeman1)) {
  name <- as.character(nodeman1[n,c("Model","NodeName")])
  if (is.null(WarehouseFetch(Nodehouse,name))) {
    cat("Building Node ",paste(name,collapse="::"),"\n")
    WarehouseSupply(Nodehouse,name)
  }
}

WarehouseFree(Nethouse,PnetName(EM1))
stopifnot(!is.valid(Nethouse,EM1))


setwd(curd)
stopSession(sess)


## End(Not run)

ralmond/Peanut documentation built on Sept. 19, 2023, 8:27 a.m.