---
title: "Introduction to imaginarycss"
author: "Sima Najafzadehkhoei"
date: today
vignette: >
  %\VignetteIndexEntry{Introduction to imaginarycss}
  %\VignetteEngine{quarto::html}
  %\VignetteEncoding{UTF-8}
---

# Introduction

The `imaginarycss` package provides tools for analyzing **Cognitive Social
Structures** (CSS), focusing on the discrepancies between actual social
networks and individuals' perceptions of those networks. The package
implements the methods described in Tanaka and Vega Yon (2023),
"Imaginary Structures as Evidence of Social Cognition"
(doi: [10.1016/j.socnet.2023.11.005](https://doi.org/10.1016/j.socnet.2023.11.005)).

## What Are Cognitive Social Structures?

Cognitive Social Structures (CSS) represent how individuals perceive the
entire social network around them. While traditional network analysis asks
"Who is connected to whom?", CSS analysis asks "Who *thinks* who is
connected to whom?"

When we compare these perceptions to the actual network structure, we can
identify various types of perceptual errors, including:

- **False positives**: perceiving connections that don't exist.
- **False negatives**: missing connections that do exist.
- **Reciprocity errors**: misperceiving whether relationships are mutual.

These errors are not random---they reveal systematic cognitive biases in how
people understand social structure.

## Key Features

- **Network construction**: create binary-array graph objects from matrices or
  lists of adjacency matrices.
- **Error analysis**: compute reciprocity errors and the full imaginary census
  (10 motif categories).
- **Tie-level accuracy**: estimate individual-level accuracy rates for
  perceiving ties and non-ties.
- **Null models**: generate null distributions for statistical testing of
  imaginary structures.

```{r}
#| label: load-package
library(imaginarycss)
```

# Creating Barry Graph Objects

The fundamental data structure in `imaginarycss` is the `barry_graph` object.
It stores a collection of networks: the first is the "true" (baseline) network
and subsequent layers represent each perceiver's view of the network.

## From a List of Matrices

The most straightforward way to create a `barry_graph` is from a list of
adjacency matrices. The first matrix is the true network; the rest are
individual perceptions.

```{r}
#| label: list-example
# True network (4 nodes)
true_net <- matrix(c(
  0, 1, 0, 1,
  1, 0, 1, 0,
  0, 1, 0, 1,
  1, 0, 1, 0
), nrow = 4, byrow = TRUE)

# Person 1 over-perceives ties (false positives)
perceived_net1 <- matrix(c(
  0, 1, 1, 1,
  1, 0, 1, 0,
  1, 1, 0, 1,
  1, 0, 1, 0
), nrow = 4, byrow = TRUE)

# Person 2 under-perceives ties (false negatives)
perceived_net2 <- matrix(c(
  0, 1, 0, 0,
  1, 0, 0, 0,
  0, 0, 0, 1,
  0, 0, 1, 0
), nrow = 4, byrow = TRUE)

graph <- new_barry_graph(list(true_net, perceived_net1, perceived_net2))
print(graph)
```

## From a Block-Diagonal Matrix

Alternatively, you can pass a single block-diagonal matrix where each
`n x n` block corresponds to a network layer.

```{r}
#| label: matrix-example
# Build an 8x8 block-diagonal matrix (two 4x4 networks)
source_ <- c(1, 2, 3, 1)
target_ <- c(2, 1, 4, 4)
source_ <- c(source_, source_[-1] + 4)
target_ <- c(target_, target_[-1] + 4)

adjmat <- matrix(0L, nrow = 8, ncol = 8)
adjmat[cbind(source_, target_)] <- 1L

graph2 <- new_barry_graph(adjmat, n = 4)
print(graph2)
```

## Inspecting Graph Attributes

Once a `barry_graph` is created, you can inspect its attributes and
extract an edge list. The `netsize` attribute gives the number of nodes
per layer, and `endpoints` marks the boundary indices of each layer
in the underlying block-diagonal structure.

```{r}
#| label: graph-attributes
#| collapse: true
# Network size and layer boundaries
data.frame(
  Attribute = c("Network size", "Endpoints"),
  Value     = c(attr(graph, "netsize"),
                paste(attr(graph, "endpoints"), collapse = ", "))
)

# First rows of the edge list
head(barray_to_edgelist(graph))
```

