# ProjectionSpec

The ProjectionSpec is connected to one or more Projections to specify a pattern of connectivity. The simplest case is a FullPrjnSpec, which specifies full connectivity, but there are many other types.

**IMPORTANT:** connectivity code ignores unit lesion status -- this allows units to be dynamically un-lesioned and still function!

# Specific Projection Types

## One-to-one and variants

- OneToOnePrjnSpec -- single unit-to-unit connections
- GpOneToOnePrjnSpec -- single unit-group to unit-group connections -- also supports random partial connectivity within groups (used to be a separate Rnd subtype)
- MarkerGpOneToOnePrjnSpec -- only connects the first unit in each unit group -- for special cases where connection is only a marker and not used for regular network processing -- not widely used anymore

- GpMapConvergePrjnSpec -- convergent projections from each unit across unit groups onto corresponding unit in receiving layer -- only sensible when each unit in group has the same representation across groups
- GpMapDivergePrjnSpec -- inverse of converge case

## Random

- RandomPrjnSpec -- makes connections purely at random with given probability for each connection
- UniformRndPrjnSpec -- permute-style randomness that results in the same number of recv connections for each unit
- PolarRndPrjnSpec -- good for topographic connections: probability of making connection function of radial distance from corresponding point in sending layer

## Tesselated regular tiling

- TesselPrjnSpec -- each recv unit connected with a specific, arbitrary pattern of sending units, with control over spacing and grouping and offsets -- this is extremely flexible and can be made to handle many unusual cases.
- GpTesselPrjnSpec -- arbitrary group-wise tesselation patterns, with either full or partial uniform random connectivity within groups (used to be called GpRnd..)

## Group-wise topographic receptive fields (RF)

- TiledGpRFPrjnSpec -- main group-wise topographic receptive field spec -- specifies 2D size of RF, spacing, and offsets -- widely used in vision models -- also supports gaussian and sigmoidal initial weight patterns
- TiledGpRFOneToOnePrjnSpec -- same as above but establishes one-to-one within-unit-group connections, appropriate when each unit has same function across unit groups (shared weights, preset weights..)
- TiledGpRFOneToOneWtsPrjnSpec -- same as above but just sets differentially strong weights for the same unit vs. other units -- a softer overall effect
- TiledSubGpRFPrjnSpec -- establishes a sub-level embedding within overall sender RF -- e.g., a 2x2 embedding within a 4x4 overall group will divide the 4x4 into alternating subgroups that each of the 2x2 group of recv unit groups will recv from -- best to see the TiledSubGpRF example in
`projection_sampler.proj`

demo project.

- TiledRFPrjnSpec -- requires recv layer to have unit groups but sending layer is treated as a flat layer -- has more flexibility than TiledGpRFPrjnSpec
- TiledNovlpPrjnSpec -- automatically tiles sending units into non-overlapping regions for given number of recv unit groups
- TiledGpMapConvergePrjnSpec -- like MapConverge but within units within each unit group in sending layer -- each recv unit receives from tiled subset of units within each unit group across the sending input layer
- TiledDivGpRFPrjnSpec

## Initial weight gradients

- GaussRFPrjnSpec -- gaussian initial weights with a moving RF window (like Tiled.. except not tied to unit group structure)
- GradientWtsPrjnSpec -- planar weight gradients on full layer connectivity

## Algorithm-specific projections

- PFCPrjnSpec -- special patterns of connectivity for PBWM PFC layers -- uses the semantics of these layers to make connecting easier
- BgPfcPrjnSpec -- special patterns of connectivity between PBWM BG -- PFC layers -- uses the semantics of these layers to make connecting easier

## Misc

- SymmetricPrjnSpec -- makes connections symmetric to existing connections -- runs as a special second pass so the other connections can already be in place.

# Projection Spec Choice Guide

Choosing the right projection spec can be difficult given the large number of options. This guide attempts to help..

See the demo project: `demo/network_misc/projection_sampler.proj`

for networks that demonstrate the use of the most popular of the following projection specs -- allows for interactive exploration as well.

First, some things are easy, like full connectivity (FullPrjnSpec) and one-to-one connectivity (OneToOnePrjnSpec), and the variant of that for unit groups, which connects entire unit groups to each other (GpOneToOnePrjnSpec).

It is when you need a more complex pattern of partial connectivity that things get a bit more difficult. The following sections consider options for various general categories of connectivity.

The TesselPrjnSpec is the most flexible non-programming prjn spec, but it takes some effort to figure out.

## Receptive Fields

A major category of connectivity is when you want receiving units to have a "receptive field" (RF) window of connections from the sending layer -- i.e., a spatially contiguous subset of sending units, typically in the shape of a square or a circle. The position of this window onto the sending layer moves with the position of the receiving unit, resulting in a **topographic** pattern of connectivity. This seems to be the default connectivity pattern in the brain.

One major subdivision in these specs is whether they depend on having the receiving units organized into unit groups, where each such group shares a common pattern of connectivity. This is analogous to the hypercolumn or minicolumn in the brain.

The following list is organized in rough order of complexity, with simplest first -- use the simplest one that fits your needs, and you may need to experiment a bit to find the right one.

### No Recv Unit Groups

- GaussRFPrjnSpec -- this is perhaps the simplest RF prjn spec -- it creates a square RF window of a specified width, and that window moves a fixed amount for every increment in receiving unit position, allowing for overlapping and non-overlapping connections, and it (optionally) initializes the weights to a gaussian function of the distance from the center of the receptive field. This is useful for self-projections too where you want to introduce some topography into the receiving layer, such that neighboring units tend to represent similar things (as in the Kohonen-style self-organizing map).

- TesselPrjnSpec -- allows more complex prjn patterns (ellipses, or any arbitrary shape), and does not use unit groups -- can also set gaussian weights

### Recv Unit Groups

- TiledNovlpPrjnSpec -- this is a fully automatic projection (no parameters) that connects unit groups with
**non-overlapping**RF windows.

- TiledRFPrjnSpec -- a complex but very powerful spec for unit-group-based overlapping windows -- it automatically uses the relative sizes of the layers to compute the receptive field window sizes, etc, and can optionally apply to subsets of unit groups.

- GpTesselPrjnSpec -- does the same thing as TesselPrjnSpec but instead of operating on the level of individual units, it
**operates on unit groups in both sending and receiving layers**, and then allows either full or partial uniform random connectivity for those connected groups -- compare to GpOneToOnePrjnSpec)

## Various Flavors of Random

- UniformRndPrjnSpec -- no spatial constraints at all -- just randomly connects units with given probability.

- PolarRndPrjnSpec -- introduces a polar coordinate system of distance and angle away from a given sending unit location, and probability of connection is function of these coordinates -- creates a random topographic connection (see also Receptive Fields section above).

- RndGpOneToOnePrjnSpec -- does one-to-one group-wise connectivity between sending and receiving layer (
**both**must have unit groups) and then has partial random connectivity within those group-wise connections.

- GpRndTesselPrjnSpec -- does the same thing as TesselPrjnSpec but instead of operating on the level of individual units, it
**operates on unit groups in both sending and receiving layers**, and then allows partial random connectivity (or not -- can also do full) for those connected groups -- compare to RndGpOneToOnePrjnSpec)