How do I count thee? Let me count the ways?

Sheldon Cooper's favorite number

      If you are a fan of the television series "The Big Bang Theory", then you know Sheldon often wears a shirt with 73 ...

Friday, September 27, 2024

Rene Descartes walks into a bar

Rene Descartes walks into a bar, by Jerry Tuttle
I recently told the old Rene Descartes joke to a math class: Rene Descartes walks into a bar. The bartender asks, "Would you like a beer?" Descartes pauses for a moment and then replies, "I think not." Then poof - he disappears.

Of course I naively assumed my students had been exposed to the Descartes quote, "I think, therefore I am." Philosopher and mathematician Rene Descartes wrote this in French in 1637, and later in Latin as cogito, ergo sum."

After explaining the Descartes quote, I think the students understood the joke. Well, maybe it's not that funny.

But perhaps funnier to math people than you realize, is: this joke is logically flawed because the punchline is the inverse to the original conditional statement, and an inverse is not logically equivalent to the original statement.

Let P and Q be declarative sentences that can be definitively classified as either true or false. Then define:

  • Conditional Statement: If P, then Q.
  • Converse: If Q, then P.
  • Inverse: If not P, then not Q.
  • Contrapositive: If not Q, then not P

Two conditional statements are defined as logically equivalent when their truth values are identical for every possible combination of truth values for their individual declarative sentences.

P Q statement converse inverse contrapositive
TRUE TRUE TRUE TRUE TRUE TRUE
TRUE FALSE FALSE TRUE TRUE FALSE
FALSE TRUE TRUE FALSE FALSE TRUE
FALSE FALSE TRUE TRUE TRUE TRUE

The above table shows statement and contrapositive have the same truth values in columns 3 and 6, and so are logically equivalent. Statement and inverse are not logically equivalent.

The Descartes quote is, "If I think, therefore I am", or "If P then Q". The punchline is, "If I don't think, therefore I am not", or "If not P, then not Q". The punchline is the inverse, and is not logically equivalent to the quote. If P is false, then "if P then Q" is true regardless of the value of Q. So Q can be either true or false.

Occasionally on television someone, often a police detective, will make a statement where they confuse a statement with its converse or inverse, and I have been known to yell at the television.

Descartes is known for developing analytic geometry, which uses algebra to describe geometry. Descartes' rule of signs counts the roots of a polynomial by examining sign changes in its coefficients.

And before someone else feels the need to say this, I will: "Don't put Descartes before the horse." This is perhaps the punchline to changing the original joke to "A horse walks into a bar ... "

The following is R code to create truth tables. Logical is a variable type in R. Conditional statements in R are created using the fact that “If P then Q” is equivalent to “Not P or Q”. I am defining the logic rules for statement, converse, inverse, contrapositive, but I could have defined the rules for more complicated statements as well.

# Define the possible values for P and Q
P <- c(TRUE, TRUE, FALSE, FALSE)
Q <- c(TRUE, FALSE, TRUE, FALSE)

# Calculate the 4 logical rules: statement, converse, inverse, contrapositive
# (Note that “if P then Q” is equivalent to “Not P or Q”.)
P_implies_Q <- !P | Q
Q_implies_P <- !Q | P
not_P_implies_not_Q <- P | !Q
not_Q_implies_not_P <- Q | !P

# expand.grid(P, Q) would also be a good start, but I wanted a specific ordering
# Create a data frame to display the truth table
truth_table <- data.frame(
P = P,
Q = Q,
`P -> Q` = P_implies_Q,
`Q -> P` = Q_implies_P,
`!P -> !Q` = not_P_implies_not_Q,
`!Q -> !P` = not_Q_implies_not_P
)

# Print the truth table
colnames(truth_table) <- c("P", "Q", "statement", "converse", "inverse", "contrapositive")
print(truth_table)

P_variable <- "I think"
Q_variable <- "I am"

colnames(truth_table) <- c(P_variable, Q_variable, "statement", "converse", "inverse", "contrapositive")
print(truth_table)

End

Sunday, September 15, 2024

The dead body problem, and the coffee with milk problem

      Here are two problems in life we all commonly face: What time did the victim die, and is it better to put milk in your coffee right away or to wait?
      In any police show with a murder, one of the detectives will always ask this math question: "What time did the victim die?" And yes, it is a math question, whose solution dates back over 300 years to Isaac Newton. For algebra and calculus students, it is probably more interesting than a lot of word problems they see.

      Newton’s Law of Cooling states that the rate of change of the temperature of an object is proportional to the difference between its own temperature and the surrounding temperature.

         Let the temperature of the object be T(t) at time t.
         Let T0 denote the initial temperature of the object at time 0.
         Let Ts denote the temperature of the surrounding medium.

      Newton's Law of Cooling states    dT/dt = -k (T - Ts),    where k is a cooling constant and where the negative sign is for the case where the body is getting cooler. The solution of the differential equation is:

T(t) = Ts + (T0 - Ts) * e^(-k*t)

      Newton published his Law of Cooling in 1701. Modern physicists believe Newton's Law holds up well and approximates the result in some but not all situations. Large temperature differences between the object and its surroundings, or non-constant temperatures, will cause difficulties. I leave the details to the physicists.

Problem 1: The dead body problem

      Example: A dead body was 80 degrees Fahrenheit when it was discovered. Two hours later it had cooled to 75 degrees. The room is 60 degrees. What time did the body die?

Assume T0 at time of death = 98.6
Assume Ts the temperature of surrounding room = 60
Let k be the unknown cooling constant. k depends on the characteristics of the object and its environment and is often between 0.1 and 0.2.

T(t) = Ts + (T0 − Ts​) * e^(−kt)

First equation, at time of discovery:
Let t = t_0 be time of discovery.    80 = 60 + (98.6 - 60) * e^(-k*t_0)

Second equation, two hours later:
At t = t_0 + 2,    75 = 60 + (98.6 - 60) * e^(-k*(t_0 + 2))

Solve first equation for k:
80 = 60 + (98.6 - 60) * e^(-k*t_0)
20 = 38.6 * e^(-k*t_0)
e^(-k*t_0) = 20 / 38.6 = .518

Solve second equation for k:
75 = 60 + (98.6 - 60) * e^(-k*(t_0 + 2))
15 = 38.6 * e^(-k*(t_0 + 2))
e^(-k*(t_0 + 2)) = 15 / 38.6 = .389

Solve for k by taking the ratio of the two equations, noting t_0 drops out:
[e^(-k*(t_0 + 2))] / [e^(-k*t_0) ] = .389 /518
e^(-2k) = .751
-2k = LN(.751)
k = - LN(.751) / 2
k = .143

Solve for time since death from first equation
80 = 60 + (98.6 - 60) * e^(-.143*t_0)
20 = 38.6 * e^(-.143*t_0)
e^(-.143*t_0) = 20 / 38.6 = .518
-.143*t_0 = LN(.518)
t_0 = - LN(.518) / .143
t_o = 4.8 hours

The body had been cooling for 4.8 hours before it was discovered.

Problem 2: The coffee with milk problem

      Here is a different application of Newton's Law of Cooling.

      Example: Who drinks the hotter coffee after five minutes: The person who puts milk in right away and then waits five minutes, or the person who waits five minutes and then puts in milk?

Assume initial temperature of coffee, T0 = 200 F
Assume temperature of the room, Ts = 72 F
Assume initial temperature of the milk, Tm = 40 F
Assume the mixture is 80% coffee and 20% milk
Assume cooling constant k = 0.1.

Case 1: Add cold milk immediately

mixture T(0) = .80*200 + .20*40 = 168
mixture T(5) = 72 + (168 − 72) * e^(−0.1*5) = 130.23

Case 2: Wait 5 minutes, then add room temperature milk

coffee T(5) = 72 + (200 - 72)*e^(-0.1*5) = 149.64
milk T(5) = 72 + (40 - 72)*e^(-0.1*5) = 52.59
mixture T(5) = .80*149.64 + .20*52.59 = 130.23

The conclusion is that cases 1 and 2 give the same temperature! However, there is also a case 3.

Case 3: Wait 5 minutes, then add cold milk

coffee T(5) = 72 + (200 - 72)*e^(-0.1*5) = 149.64
mixture T(5) = .80*149.64 + .20*40 = 127.71

For simplicity, I ignored a few things that probably have a minor effect on the final temperature: I assume the mixing process is instantaneous. I assume the cup does not absorb heat from the coffee. I assume stirring the mixture does accelerate heat transfer. Perhaps there are others. I can not measure the effect of these.

Thank you, Isaac Newton (who as a Brit, perhaps drank tea?).

End

Sunday, September 8, 2024

Mind reader game, and Unicode symbols

Mind reader game, and Unicode symbols, by Jerry Tuttle

Perhaps you've seen this Mind Reader game? Think of a two-digit positive whole number, such as 54. Subtract each of the two digits from your number, such as 54 - 5 - 4 = 45, and call 45 the RESULT. Examine the table of symbols below and find the SYMBOL that corresponds with your RESULT. Concentrate on the SYMBOL, and remember it. Then scroll down below, and I will read your mind to predict your SYMBOL.

Before I get to my prediction, let's talk about Unicode symbols.

Unicode symbols

Unicode is a standard international system that assigns a unique Unicode number to each letter, digit, or symbol. This permits thousands of symbols to be written across different platforms, programs, and languages. An example of a Unicode number is "U+" followed by a hex number, such as U+1F499.

The table of symbols in the Mind Reader game is based on plotting a variety of Unicode symbols by printing their Unicode numbers.

A Unicode symbol is printed in R with its Unicode number, but beginning with a backslash to escape the U, and omitting the plus sign. For example, here is how to print a heart symbol.

print("\U1F499")
"💙"

Example with Hebrew letters

Let's spell out the Hebrew word shalom , letter by letter, with each letter's Unicode number, and then use the R paste command to paste the letters together.

    shin <- "\U05E9"     # "ש"
    kamatz <- "\U05B7"     # vowel as two perpendicular lines "ַ"
    lamed <- "\U05DC"     # "ל"
    vav <- "\U05D5"     # "ו"
    final_mem <- "\U05DD"     # "ם"
    shin_with_kamatz <- "\U05E9\U05B7"     # "שַ"
    paste(shin_with_kamatz, lamed, vav, final_mem, sep = "")

"שַלום"

Note that the letters are entered in the paste statement in order of first Hebrew letter, second Hebrew letter, etc., but they are printed in Hebrew right-to-left. Also, a better choice than vav is cholam, which is vav with a dot above it, "\U05BA", but this doesn't print for me.

My prediction

Here is my prediction of your symbol:

Want to play again? Think of another two-digit positive whole number, such as 54. Subtract each of the two digits from your number, such as 54 - 5 - 4 = 45, and call 45 the RESULT. Examine the table of symbols below and find the SYMBOL that corresponds with your RESULT. Concentrate on the SYMBOL, and remember it. Then scroll down below, and I will read your mind to predict your SYMBOL.

Plotting with Unicode characters

Tired of plotting points with those boring 25 pch symbols? You can use Unicode symbols, but you can't simply use pch = . Here for no good reason I use a heart and a thumbs up.

library(ggplot2)
x <- seq(from=0,to=4, by=1)
y <- x^2
z <- exp(x)
df1 <- data.frame(x, y)
df2 <- data.frame(x, z)
heart <- "\U1F499"
thumbs_up <- "\U1F44D"
# Create a custom function to convert Unicode values to GeomPoint
custom_points <- function(data, mapping, ..., shape = heart) {
    ggplot2::geom_point(data = data, mapping = mapping, ..., shape = shape)
}
ggplot() +
    custom_points(data = df1, aes(x = x, y = y, color = "y = x^2"), shape = heart, size=5) +
    geom_line(data = df1, aes(x = x, y = y, color = "y = x^2")) +
    custom_points(data = df2, aes(x = x, y = z, color = "z = exp(x)"), shape = thumbs_up, size=5) +
    geom_line(data = df2, aes(x = x, y = z, color = "z = exp(x)")) +
    ggtitle("Plot with Unicode points") +
    labs(color = "Function") +
    theme(legend.position = c(0.15, 0.85),
      plot.title = element_text(color="black", size=14, face="bold"),
      legend.text = element_text(color="black", size=10, face="bold"))

My second prediction

Here is my second prediction:

Here is the code for the mind reader:

# start with arbitrary set of unicode symbols
description =
    c("a_bengali","a_gurmukhi","approximately_equal","biohazard","black_diamond",
    "black_heart","black_scissors","mercury",
    "mushroom","nya_gujarati",
    "section","snowflake",
    "snowman","teardrop_spoked_asterisk","thunderstorm",
    "umbrella_raindrops","white_cross","white_florette",
    "zhe_cyrillic", "airplane",
   "black_right_arrow","black_telephone","blue_heart",
    "two_xs","hot_beverage","green apple","pill",
    "trophy","thumbs_up")

unicode=
    c("\U0986","\U0A05","\U2248","\U2623","\U25C6","\U2665","\U2702","\U263F",
    "\U1F344","\U0A9E","\U00A7","\U2746",
    "\U26C4","\U273B","\U2608","\U2614","\U271E","\U2740",
    "\U04DC","\U2708","\U27A4","\U260E","\U1F499","\U1F9E0","\U2615","\U1F34F",
   "\U1F48A","\U1F3C6","\U1F44D")

df_uni <- data.frame(cbind(description, unicode))
n <- nrow(df_uni)
x <- seq(1,n,1)
s <- sample(x, 1)
diag <- unicode[s]
diag
x <- x[-x[s]]
y <- sample(x, 100, replace = TRUE)     # randomly choose 100 symbols

df <- data.frame(matrix(ncol = 20, nrow = 10))

for (i in seq(1, 19, by = 2)) {
    df[, i] <- seq(99, 9, -10) - (i - 1) / 2 # row i, odd columns
    df[, i + 1] <- y[((i - 1) / 2 * 10 + 1):((i - 1) / 2 * 10 + 10)] # row i, even columns
    df[, i + 1] <- unicode[df[, i + 1]]
}

for (i in 1:10) {
    df[i, 20 - 2*(i - 1)] <- diag
}

op <- par(bg = "thistle")
plot(x = c(0, 50*20), y = c(0, 50*10), type = "n", xlab = "", ylab = "", xaxt = 'n',
    yaxt = 'n', main = "Mind Reader # 1", cex=2, font=2)

# Loop through each cell of the dataframe to draw rectangles and add text
for (i in 1:20) {
    for (j in 1:10) {
      # Determine the color based on whether the column index is odd or even
      fill_color <- ifelse(i %% 2 == 1, "cornsilk", "lightblue")

      # Draw rectangle with the determined color
      rect(50*(i-1), 50*(10-j), 50*i, 50*(10-j+1), col = fill_color, border = "blue")

      # Add text in the center of the rectangle
      text(50*(i-1) + 25, 50*(10-j) + 25, df[j, i], col = "navyblue", cex = 1, font = 2)
      }
}

# Restore original graphics parameters
par(op)

Hint on prediction

The prediction relies on a little algebra. As a hint, your original two-digit whole number is of the form, 10*T + U. What happens when you subtract the digits?

End

<