.packageName <- "ResistorArray"
"array.resistance" <-
function (x.offset, y.offset, rows.of.resistors, cols.of.resistors, 
    give.pots = FALSE) 
{
    "get.1d.index" <- function(rownum, colnum, R, C) {
        (colnum - 1) * R + rownum
    }
    total.n.resistors <- rows.of.resistors * cols.of.resistors
    A <- makefullmatrix(rows.of.resistors, cols.of.resistors)
    current.in.x <- cols.of.resistors%/%2
    current.in.y <- rows.of.resistors%/%2
    current.out.x <- current.in.x + x.offset
    current.out.y <- current.in.y + y.offset
    current.in.1d <- get.1d.index(current.in.y, current.in.x, 
        rows.of.resistors, cols.of.resistors)
    current.out.1d <- get.1d.index(current.out.y, current.out.x, 
        rows.of.resistors, cols.of.resistors)
    if (give.pots) {
        return(matrix(resistance(A, current.in.1d, current.out.1d, 
            give.pots = TRUE), rows.of.resistors, cols.of.resistors))
    }
    else {
        return(resistance(A, current.in.1d, current.out.1d, give.pots = FALSE))
    }
}
"circuit" <-
function (L, v, currents = 0, use.inverse = FALSE, give.internal = FALSE) 
{
    free.v <- is.na(v)
    fixed.v <- !free.v
    A <- L[fixed.v, fixed.v, drop = FALSE]
    B <- L[fixed.v, free.v, drop = FALSE]
    D <- L[free.v, free.v, drop = FALSE]
    v.known <- v[fixed.v, drop = FALSE]
    I <- v
    I[] <- currents
    if (any(free.v)) {
      if(use.inverse){
          v[free.v] <- crossprod(solve(D), I[free.v] - crossprod(B, v.known))
      } else {
          v[free.v] <- solve(D, I[free.v] - crossprod(B, v.known))
      }
    }
    I[fixed.v] <- crossprod(A, v.known) + B %*% v[free.v]
    out <- list(potentials = v, currents = I)
    if (give.internal) {
        jj <- L
        jj[] <- v
        pot.diffs <- jj - t(jj)
        return(list(potentials = v, currents = I, internal.currents = L * 
            pot.diffs, power = -L * pot.diffs^2, total.power = -sum(L * 
            pot.diffs^2)/2))
    }
    else {
        return(out)
    }
}
"cube" <-
function (x = 1) 
{
    out <- matrix(0, 8, 8)
    out[platonic("cube")] <- -1/x
    out <- out + t(out)
    diag(out) <- -apply(out, 2, sum)
    out
}
"currents" <-
function (L, earth.node, input.node) 
{
    edges <- which(L != 0 & row(L) < col(L), arr.ind = TRUE)
    rownames(edges) <- NULL
    colnames(edges) <- c("from", "to")
    volts <- resistance(L, earth.node = earth.node, input.node = input.node, 
        g = TRUE)
    cbind(edges, (volts[edges[, 1]] - volts[edges[, 2]]) * L[edges])
}
"currents.matrix" <-
function (L, earth.node, input.node) 
{
    out <- L
    out[] <- resistance(L, earth.node, input.node, g = TRUE)
    out <- L * (out - t(out))
    out
}
"dodecahedron" <-
function (x = 1) 
{
    out <- matrix(0, 20, 20)
    out[platonic("dodecahedron")] <- -1/x
    out <- out + t(out)
    diag(out) <- -apply(out, 2, sum)
    return(out)
}
"icosahedron" <-
function (x = 1) 
{
    out <- matrix(0, 12, 12)
    out[platonic("icosahedron")] <- -1/x
    out <- out + t(out)
    diag(out) <- -apply(out, 2, sum)
    return(out)
}
"ladder" <-
function (n, x = 1, y = 1, z = NULL) 
{
    out <- matrix(0, n, n)
    jj.series <- rbind(cbind(1, 2:n), cbind(2:(n - 1), 3:n))
    out[jj.series[1:(n - 1), ]] <- -1/x
    out[jj.series[n:(2 * n - 3), ]] <- -1/y
    if (!is.null(z)) {
        out[jj.series] <- -1/z
    }
    out <- out + t(out)
    diag(out) <- -apply(out, 2, sum)
    out
}
"makefullmatrix" <-
function (R, C) 
{
    "get.1d.index" <- function(rownum, colnum, R, C) {
        (colnum - 1) * R + rownum
    }
    out <- diag(4, nrow = R * C)
    jj <- row(out) - col(out)
    out[jj == +1] <- -1
    out[jj == -1] <- -1
    out[jj == +R] <- -1
    out[jj == -R] <- -1
    out[jj == +R * C - R] <- -1
    out[jj == -R * C + R] <- -1
    out[1, R * C] <- -1
    out[R * C, 1] <- -1
    return(out)
}
"octahedron" <-
function (x = 1) 
{
    out <- matrix(0, 6, 6)
    out[platonic("octahedron")] <- -1/x
    out <- out + t(out)
    diag(out) <- -apply(out, 2, sum)
    return(out)
}
"platonic" <-
function (a) 
{
    switch(a, tetrahedron = matrix(c(1, 1, 1, 2, 2, 3, 2, 3, 
        4, 3, 4, 4), ncol = 2), cube = matrix(c(1, 1, 1, 2, 2, 
        3, 3, 4, 5, 5, 6, 7, 2, 4, 5, 3, 6, 4, 7, 8, 6, 8, 7, 
        8), ncol = 2), octahedron = matrix(c(1, 1, 1, 1, 2, 2, 
        2, 3, 3, 4, 4, 5, 2, 3, 4, 5, 3, 5, 6, 4, 6, 5, 6, 6), 
        ncol = 2), dodecahedron = matrix(c(1, 1, 1, 2, 2, 3, 
        3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, 
        14, 15, 16, 16, 17, 18, 19, 2, 5, 6, 3, 7, 4, 8, 5, 9, 
        10, 11, 12, 12, 13, 13, 14, 14, 15, 11, 15, 16, 17, 18, 
        19, 20, 17, 20, 18, 19, 20), ncol = 2), icosahedron = matrix(c(1, 
        1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 
        6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 2, 3, 4, 5, 8, 3, 
        5, 6, 9, 4, 6, 7, 7, 8, 10, 8, 9, 11, 7, 9, 12, 10, 12, 
        10, 11, 11, 12, 11, 12, 12), ncol = 2))
}
"resistance" <-
function (A, earth.node, input.node, current.input.vector = NULL,
           give.pots = FALSE) 
{
    potentials <- rep(0, nrow(A))
    A <- A[-earth.node, -earth.node]
    if (is.null(current.input.vector)) {
        current.input.vector <- potentials
        current.input.vector[input.node] <- 1
    }
    else {
        give.pots <- TRUE
    }
    potentials[-earth.node] <- solve(A, current.input.vector[-earth.node])
    if (give.pots) {
        return(potentials)
    }
    else {
        return(potentials[input.node])
    }
}
"series" <-
function (x) 
{
    n <- length(x)
    out <- matrix(0, n + 1, n + 1)
    jj.series <- cbind(1:n, 2:(n + 1))
    out[jj.series] <- -1/x
    out <- out + t(out)
    diag(out) <- -apply(out, 2, sum)
    out
}
"tetrahedron" <-
function (x = 1) 
{
    out <- matrix(0, 4, 4)
    out[platonic("tetrahedron")] <- -1/x
    out <- out + t(out)
    diag(out) <- -apply(out, 2, sum)
    out
}
"Wu" <-
function (L) 
{
    jj <- eigen(L)
    n <- nrow(L)
    evals <- jj$values
    evecs <- t(jj$vectors)
    evals[n] <- Inf
    evecs <- evecs/sqrt(evals)
    out <- apply(evecs, 2, function(y) {
        apply(evecs, 2, function(x) {
            sum((x - y)^2)
        })
    })
    return(out)
}
