/
lexcelPS.R
162 lines (142 loc) · 5.61 KB
/
lexcelPS.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#' @export
`[.LP*Scores` <- function(x, i, ...) structure(unclass(x)[i], class = 'LP*Scores')
#' @export
`==.LP*Scores` <- function(a, b) {identical(a[[1]], b[[1]])}
#' @export
`>.LP*Scores` <- function(a, b) {
a <- a[[1]]
b <- b[[1]]
if(ncol(a) != ncol(b)) {
return(ncol(a) < ncol(b))
}
i <- which(a != b)
length(i) > 0 && a[i[1]] > b[i[1]]
}
#' @export
`is.na.LP*Scores` <- function(x) FALSE
#' LP* Ranking
#'
#' Calculate the \eqn{L^{p^*}}{L^p*} scores.
#'
#' @template lexcel/frequencyMatrixDoc
#' @details
#' For \eqn{i, j \in N}{i, j in N}, the social ranking solution \eqn{L^{p^*}}{L^p*} then ranks \eqn{i} strictly above \eqn{j} if one of the following conditions hold:
#'
#' 1. \eqn{\lbrace i \rbrace \succ \lbrace j \rbrace}{\{i\} > \{j\}};
#' 2. \eqn{\lbrace i \rbrace, \lbrace j \rbrace \in \Sigma_k}{\{i\}, \{j\} in E_k} and there exists a row \eqn{p_0 \in \lbrace 2, \dots, |N|\rbrace}{p_0 in \{2, ..., |N|-1\}} and column \eqn{q_0 \in \lbrace 1, \dots, k-1\rbrace}{q_0 in \{1, ..., k-1\}} such that:
#' \deqn{(M^\succsim_i)_{p,q} = (M^\succsim_j)_{p,q}\quad \forall p < p_0, q < k,}{(M^(>=)_i)_(p,q) = (M^(>=)_j)_(p,q) for all p < p_0, q < k,}
#' \deqn{(M^\succsim_i)_{p_0,q} = (M^\succsim_j)_{p_0,q}\quad \forall q < q_0,\text{ and}}{(M^(>=)_i)_(p_0,q) = (M^(>=)_j)_(p_0,q) for all q < q_0, and}
#' \deqn{(M^\succsim_i)_{p_0,q_0} > (M^\succsim_j)_{p_0,q_0}.}{(M^(>=)_i)_(p_0,q_0) > (M^(>=)_j)_(p_0,q_0).}
#'
#' @section Example:
#'
#' Let \eqn{\succsim: (123 \sim 12 \sim 2) \succ (13 \sim 23) \succ (1 \sim 3 \sim \{\})}{>=: (123 ~ 13 ~ 2) > (12 ~ 23) > (1 ~ 3 ~ \{\})}.
#' From this, we get the following three matrices:
#'
#' \deqn{
#' M^\succsim_1 = \begin{bmatrix}
#' 0 & 0 & 1\\
#' 1 & 1 & 0\\
#' 1 & 0 & 0
#' \end{bmatrix}
#' M^\succsim_2 = \begin{bmatrix}
#' 1 & 0 & 0\\
#' 1 & 0 & 1\\
#' 1 & 0 & 0
#' \end{bmatrix}
#' M^\succsim_3 = \begin{bmatrix}
#' 0 & 0 & 1\\
#' 0 & 2 & 0\\
#' 1 & 0 & 0
#' \end{bmatrix}
#' }{
#' M^(>=)_1 = matrix(c(0,1,1,0,1,0,1,0,0),nrow=3)\\
#' M^(>=)_2 = matrix(c(1,1,1,0,0,0,0,1,0),nrow=3)\\
#' M^(>=)_3 = matrix(c(0,0,1,0,2,0,1,0,0),nrow=3)
#' }
#'
#' \eqn{(M^\succsim_2)_{2,3}}{(M^(>=)_2)_(2,3)} in this context refers to the value in the second row and third column of element 2, in this case \eqn{1}{1}.
#'
#' In the example, \eqn{2}{2} will be immediately put above \eqn{1}{1} and \eqn{3}{3} because \eqn{\lbrace 2 \rbrace \succ \lbrace 1 \rbrace}{\{2\} > \{1\}} and \eqn{\lbrace 2 \rbrace \succ \lbrace 3 \rbrace}{\{2\} > \{3\}}.
#' Since \eqn{\lbrace 1 \rbrace \sim \lbrace 3 \rbrace}{\{1\} ~ \{3\}}, we next consider the coalitions of size 2. Here, it turns out that \eqn{(M^\succsim_1)_{2,1} = 1 > 0 = (M^\succsim_3)_{2,1}}{(M^(>=)_1)_(2,1) = 1 > 0 = (M^(>=)_3)_(2,1)},
#' setting \eqn{3}{3} to be the least preferred option (this is opposed to the \eqn{L^p}{L^p} relation, which has no strict preference of \eqn{1}{1} over \eqn{3}{3}).
#'
#' As alluded to, \eqn{L^{p^*}}{L^p*} is similar to \eqn{L^p}{L^p}, [`LPRanking()`], in that it first considers the singleton coalitions, then sequentially every coalition of size 2 and above that ranks better than the corresponding singleton.
#' It can be assumed, however, that \eqn{L^{p^*}}{L^p*} is more granular, as it doesn't throw away any information about _which_ equivalence class these bigger coalitions belong to.
#'
#' @section Alterations:
#'
#' The matrices as described above and in \insertRef{beal2022lexicographic}{socialranking} can be investigated with the [`L1Scores()`] function.
#'
#' `LPSScores()` discards some redundant information, most notably all columns from each element's singleton class and the ones thereafter.
#' The first row is also removed, as all values there are guaranteed to be 0.
#'
#' For the example above, this would actually result in the matrices
#'
#' \preformatted{
#' matrix(c(1,1, 1,0), nrow=2)
#' matrix(numeric(), nrow=2)
#' matrix(c(0,1, 2,0), nrow=2)
#' }
#'
#' @section Aliases:
#'
#' For better discoverability, `lexcelPSScores()` and `lexcelPSRanking()` serve as aliases for `LPSScores()` and `LPSRanking()`, respectively.
#'
#' @template param/powerRelation
#' @template param/elements
#'
#' @family ranking solution functions
#'
#' @references
#' \insertRef{beal2022lexicographic}{socialranking}
#'
#' @return Score function returns a list of type `LP*Scores` and length of `powerRelation$elements`
#' (unless parameter `elements` is specified).
#' Each index contains a matrix with `length(powerRelation$elements)` rows and a variable number of columns, depending on the equivalence class index containing the singleton coalition of that element (matrix can have 0 columns).
#'
#' @examples
#' pr <- as.PowerRelation("(123 ~ 12 ~ 2) > (13 ~ 23) > (1 ~ 3 ~ {})")
#' scores <- LPSScores(pr)
#' scores$`1`
#' # [,1] [,2]
#' # [1,] 1 1
#' # [2,] 1 0
#'
#' scores$`2`
#' #
#' # [1,]
#' # [2,]
#'
#' LPSRanking(pr)
#' # 2 > 1 > 3
#'
#' @export
LPSScores <- function(powerRelation, elements = powerRelation$elements) {
# --- checks (generated) --- #
stopifnot(is.PowerRelation(powerRelation))
# --- end checks --- #
res <- L1Scores(powerRelation, elements)
cols <- sapply(res, function(m) which(m[1,] > 0)[1])
structure(
lapply(seq_along(res), function(i) if(is.na(cols[i])) res[[i]][-1,] else res[[i]][-1,-(cols[i]:ncol(res[[i]])), drop=FALSE]),
names=names(res),
class='LP*Scores'
)
}
#' `LPSRanking()` returns the corresponding ranking.
#'
#' @rdname LPSScores
#'
#' @template return/ranking
#'
#' @export
LPSRanking <- function(powerRelation) {
doRanking(LPSScores(powerRelation))
}
#' @rdname LPSScores
#' @export
lexcelPSScores <- LPSScores
#' @rdname LPSScores
#' @export
lexcelPSRanking <- LPSRanking