Nothing
## ----include = FALSE----------------------------------------------------------
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
## ----setup--------------------------------------------------------------------
library(musicMCT)
## -----------------------------------------------------------------------------
tc(c(0, 2, 4, 5), c(0, 7))
## -----------------------------------------------------------------------------
scale_from_genus <- function(genus) {
sd2 <- genus[1]
sd3 <- genus[2]
if (sd2 > sd3) {
return(NA)
}
tc(c(0, sd2, sd3, 5), c(0, 7))
}
## ----out.width = '75%', echo = FALSE------------------------------------------
knitr::include_graphics("img/vhd_plane_embedding.png")
## ----fig.width=5, fig.height=5, fig.fullwidth=TRUE----------------------------
ionian <- scale_from_genus(c(2, 4)) #1
dorian <- scale_from_genus(c(2, 3)) #2
phrygian <- scale_from_genus(c(1, 3)) #3
double_harmonic <- scale_from_genus(c(1, 4)) #4
enharmonic <- scale_from_genus(c(.5, 1)) #5
demo_scales <- cbind(ionian, dorian, phrygian, double_harmonic, enharmonic)
## ----fig.width=5, fig.height=5, fig.fullwidth=TRUE----------------------------
tetra_plot <- function(scales, title, ...) {
oldpar <- par(bg='aliceblue')
on.exit(par(oldpar))
plot(scales[2, ],
scales[3, ],
xlab="Height of scale degree 2", xlim=c(-.05, 5.05),
ylab="Height of scale degree 3", ylim=c(-.01, 5.01),
...)
grid(col="gray35")
mtext(side=3, title, font=2, line=1)
}
tetra_plot(demo_scales,
"Location of 5 Reference Scales in the tc() Plane",
pch=sapply(1:5, toString))
## ----fig.width=5, fig.height=5, fig.fullwidth=TRUE----------------------------
# Invert the original enharmonic scale:
inverted_enharmonic <- tni(enharmonic, 0)
# Define a new enharmonic scale based on where we expect to plot it:
new_enharmonic <- scale_from_genus(c(4, 4.5))
# The two are the same:
rbind(inverted_enharmonic, new_enharmonic)
# Let's plot them:
demo_scales <- cbind(demo_scales, inverted_enharmonic)
tetra_plot(demo_scales,
"Location of 6 Reference Scales in the tc() Plane",
pch=sapply(1:6, toString))
## -----------------------------------------------------------------------------
show_landmarks <- function() {
points(demo_scales[2, ], demo_scales[3, ], pch=19, cex=2.5, col="white")
points(demo_scales[2, ], demo_scales[3, ], pch=sapply(1:6, toString), font=2)
}
## -----------------------------------------------------------------------------
num_points <- 4000
parhypatai <- runif(num_points, 0, 5)
lichanoi <- runif(num_points, 0, 5)
inputs <- rbind(parhypatai, lichanoi) |> apply(MARGIN=2, FUN=sort)
random_scales <- apply(inputs, 2, scale_from_genus)
all_signvectors <- apply(random_scales, 2, signvector)
unique_signvectors <- all_signvectors |> unique(MARGIN=2) |> apply(MARGIN=2, FUN=toString)
unique_signvectors <- sort(unique_signvectors)
length(unique_signvectors)
## ----echo=FALSE---------------------------------------------------------------
new_order <- c(1, 15, 17, 21, 3, 19, 25, 11, 9, 13, 5, 23, 7, 2, 16, 18, 22, 4, 20, 26, 12, 10, 6, 24, 8, 14)
unique_signvectors <- unique_signvectors[new_order]
## ----fig.width=5, fig.height=5, fig.fullwidth=TRUE----------------------------
match_sv <- function(sv) {
res <- which(unique_signvectors == toString(sv))
if (length(res)==0) {
return(0)
}
res
}
scalar_colors <- apply(all_signvectors, 2, match_sv)
display_colors <- palette.colors(26, palette="Polychrome 36")[scalar_colors]
tetra_plot(random_scales,
"26 Scalar Colors in the tc() Plane",
col=display_colors,
pch=20)
show_landmarks()
## -----------------------------------------------------------------------------
howfree(double_harmonic)
## -----------------------------------------------------------------------------
howfree(ionian)
howfree(dorian)
howfree(phrygian)
## ----fig.width=5, fig.height=5, fig.fullwidth=TRUE----------------------------
projected_scales <- apply(random_scales, 2, match_flat, target_scale=double_harmonic)
colors_for_projected_scales <- rep("black", num_points)
scales_for_fig5 <- cbind(random_scales, projected_scales)
colors_for_fig5 <- c(display_colors, colors_for_projected_scales)
tetra_plot(scales_for_fig5,
"Double Harmonic's Flat as a Line of Black Points",
col=colors_for_fig5,
pch=20)
show_landmarks()
## -----------------------------------------------------------------------------
test_for_pwf <- apply(projected_scales, 2, isgwf)
table(test_for_pwf)
## ----fig.width=5, fig.height=5, fig.fullwidth=TRUE----------------------------
evenness_values <- apply(projected_scales, 2, evenness)
sizes_for_fig6 <- c(rep(1, num_points), max(evenness_values)-evenness_values)
tetra_plot(scales_for_fig5,
"Line Thickness Represents Scale Evenness",
col=colors_for_fig5,
pch=20,
cex=sizes_for_fig6)
show_landmarks()
## ----fig.width=5, fig.height=5, fig.fullwidth=TRUE----------------------------
zoomed_tetra_plot <- function(scales, title, ...) {
oldpar <- par(bg='aliceblue')
on.exit(par(oldpar))
plot(scales[2,],
scales[3, ],
xlab="Height of scale degree 2", xlim=c(0.95, 2.05),
ylab="Height of scale degree 3", ylim=c(2.99, 4.01),
...)
grid(col="gray35")
mtext(side=3, title, font=2, line=1)
}
zoomed_parhypatai <- runif(num_points, 1, 2)
zoomed_lichanoi <- runif(num_points, 3, 4)
zoomed_inputs <- rbind(zoomed_parhypatai, zoomed_lichanoi)
zoomed_sets <- apply(zoomed_inputs, 2, scale_from_genus)
zoomed_signvectors <- apply(zoomed_sets, 2, signvector)
zoomed_scalar_colors <- apply(zoomed_signvectors, 2, match_sv)
zoomed_display_colors <- palette.colors(26, palette="Polychrome 36")[zoomed_scalar_colors]
points_for_fig7 <- cbind(zoomed_sets, projected_scales)
colors_for_fig7 <- c(zoomed_display_colors, colors_for_projected_scales)
sizes_for_fig7 <-c(rep(1, num_points), 3^(evenness(double_harmonic)-evenness_values))
zoomed_tetra_plot(points_for_fig7,
"Scalar Colors in the tc() Plane's Most Interesting Zone",
col=colors_for_fig7,
pch=20,
cex=sizes_for_fig7)
show_landmarks()
## -----------------------------------------------------------------------------
which_most_even <- which.min(evenness_values)
projected_scales[, which_most_even]
## -----------------------------------------------------------------------------
naive_guess <- scale_from_genus(c(1+(2/3), 3+(1/3)))
actual_optimum <- scale_from_genus(c(23/14, 47/14))
evenness(naive_guess)
evenness(actual_optimum)
## ----fig.width=5, fig.height=5, fig.fullwidth=TRUE----------------------------
zoomed_tetra_plot(points_for_fig7,
"Most Even Scale at the Point Labeled #7",
col=colors_for_fig7,
pch=20,
cex=sizes_for_fig7)
show_landmarks()
points(23/14, 47/14, pch=19, cex=2.5, col="white")
points(23/14, 47/14, pch="7", font=2)
## -----------------------------------------------------------------------------
howfree(naive_guess)
iswellformed(naive_guess)
## ----fig.width=5, fig.height=5, fig.fullwidth=TRUE----------------------------
# Define a grid that covers the tc() plane evenly.
# x and y both range from 0 to 5 but with slight offsets so that we only see 3-D scales:
grid_subdivisions <- 100
x <- seq(0.001, 4.999, length.out=grid_subdivisions)
y <- seq(0, 4.98, length.out=grid_subdivisions)
# Calculate the scale structures. (Cf. the definition of `scalar_colors` for Figure 4.)
color_from_point <- function(x, y) scale_from_genus(c(x, y)) |> signvector() |> match_sv()
scalar_colors <- outer(x, y, Vectorize(color_from_point))
# Create visuals
color_palette <- c("aliceblue", palette.colors(26, palette="Polychrome 36"))
oldpar <- par(bg="aliceblue")
image(x, y, z=scalar_colors, col=color_palette,
xlab="Height of Scale Degree 2", ylab="Height of Scale Degree 3")
mtext(side=3, "26 Scalar Colors in the tc() Plane", font=2, line=1)
show_landmarks()
## ----echo=FALSE---------------------------------------------------------------
par(oldpar)
## ----fig.width=7, fig.height=5, fig.fullwidth=TRUE----------------------------
# Position plot and legend
oldpar <- par(no.readonly=TRUE)
layout(matrix(c(1, 2), ncol=2), widths=c(5, 2))
# Plot the evenness values
measure_evenness <- function(x, y) scale_from_genus(c(x, y)) |> evenness()
evenness_values <- outer(x, y, Vectorize(measure_evenness))
fig10_palette <- hcl.colors(100, palette="Green-Brown")
par(bg="aliceblue")
image(x, y, z=evenness_values, col=fig10_palette,
xlab="Height of Scale Degree 2", ylab="Height of Scale Degree 3")
points(23/14, 47/14, pch=4, col="white", cex=1.5)
mtext(side=3, "Evenness of Scales in the tc() Plane", font=2, line=1)
# Make the legend
color_legend <- as.raster(matrix(rev(fig10_palette), ncol=1))
ymin <- min(evenness_values[!is.na(evenness_values)])
ymax <- max(evenness_values[!is.na(evenness_values)])
plot(c(0, 1), c(ymin, ymax), type="n", axes=FALSE, xlab="", ylab="Evenness")
rasterImage(color_legend, 0, ymin, 1, ymax)
axis(2, at = round(seq(ymin, ymax, length.out=5), 2))
## ----echo=FALSE---------------------------------------------------------------
par(oldpar)
## ----fig.width=7, fig.height=5, fig.fullwidth=TRUE----------------------------
oldpar <- par(no.readonly=TRUE)
layout(matrix(c(1, 2), ncol=2), widths=c(5, 2))
# Plot the brightness ratio values
measure_ratio <- function(x, y) scale_from_genus(c(x, y)) |> ratio()
ratio_values <- outer(x, y, Vectorize(measure_ratio))
fig11_palette <- hcl.colors(100, palette="Green-Brown")
par(bg="aliceblue")
image(x, y, z=ratio_values, col=fig11_palette,
xlab="Height of Scale Degree 2", ylab="Height of Scale Degree 3")
mtext(side=3, '"Brightness Ratio" Values in the tc() Plane', font=2, line=1)
# Make the legend
color_legend <- as.raster(matrix(rev(fig11_palette), ncol=1))
ymin <- min(ratio_values[!is.na(ratio_values)])
ymax <- max(ratio_values[!is.na(ratio_values)])
plot(c(0, 1), c(ymin, ymax), type="n", axes=FALSE, xlab="", ylab="Brightness Ratio")
rasterImage(color_legend, 0, ymin, 1, ymax)
axis(2, at = round(seq(ymin, ymax, length.out=5), 2))
## ----echo=FALSE---------------------------------------------------------------
par(oldpar)
## ----fig.width=7, fig.height=5, fig.fullwidth=TRUE----------------------------
oldpar <- par(no.readonly=TRUE)
layout(matrix(c(1, 2), ncol=2), widths=c(5, 2))
# Plot the brightness ratio values
measure_ratio <- function(x, y) scale_from_genus(c(x, y)) |> ratio()
ratio_values <- outer(x, y, Vectorize(measure_ratio))
fig11_palette <- hcl.colors(100, palette="Green-Brown")
par(bg="aliceblue")
image(x, y, z=ratio_values, col=fig11_palette,
xlab="Height of Scale Degree 2", ylab="Height of Scale Degree 3")
mtext(side=3, 'Contour Plot of "Brightness Ratio" in the tc() Plane', font=2, line=1)
# Add the contour plot
contour(x, y, z=ratio_values, add=TRUE)
# Make the legend
color_legend <- as.raster(matrix(rev(fig11_palette), ncol=1))
ymin <- min(ratio_values[!is.na(ratio_values)])
ymax <- max(ratio_values[!is.na(ratio_values)])
plot(c(0, 1), c(ymin, ymax), type="n", axes=FALSE, xlab="", ylab="Brightness Ratio")
rasterImage(color_legend, 0, ymin, 1, ymax)
axis(2, at = round(seq(ymin, ymax, length.out=5), 2))
## ----echo=FALSE---------------------------------------------------------------
par(oldpar)
## ----fig.width=7, fig.height=5, fig.fullwidth=TRUE----------------------------
oldpar <- par(no.readonly=TRUE)
layout(matrix(c(1, 2), ncol=2), widths=c(5, 2))
grid_subdivisions <- 100
u <- seq(1.001, 1.999, length.out=grid_subdivisions)
v <- seq(3, 3.98, length.out=grid_subdivisions)
ratio_values2 <- outer(u, v, Vectorize(measure_ratio))
fig11_palette <- hcl.colors(100, palette="Green-Brown")
par(bg="aliceblue")
image(u, v, z=ratio_values2, col=fig11_palette,
xlab="Height of Scale Degree 2", ylab="Height of Scale Degree 3")
contour(u, v, z=ratio_values2, add=TRUE)
mtext(side=3, "\"Brightness Ratio\" at Center of tc() Plane", font=2, line=1)
# Make the legend
color_legend <- as.raster(matrix(rev(fig11_palette), ncol=1))
ymin <- min(ratio_values2[!is.na(ratio_values)])
ymax <- max(ratio_values2[!is.na(ratio_values)])
plot(c(0, 1), c(ymin, ymax), type="n", axes=FALSE, xlab="", ylab="Brightness Ratio")
rasterImage(color_legend, 0, ymin, 1, ymax)
axis(2, at = round(seq(ymin, ymax, length.out=5), 2))
## ----echo=FALSE---------------------------------------------------------------
par(oldpar)
## -----------------------------------------------------------------------------
ratio(scale_from_genus(c(1.5, 3.5)))
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.