Numerical Methods: Creation of a graph in which the function moves inwards the higher the parameter gamma

Hi Posit Community,

I am doing numerical methods and I am struggling to produce the PNG file that is enclosed:

Below is my code using reprex(), in which I try to replicate this, but obtained a completely different graph:

# Required libraries
if (!require("pacman")) install.packages("pacman")
pacman::p_load(ggplot2, tidyverse, hrbrthemes, gridExtra, cubature, formattable, rootSolve, readr, pracma, here, fs, truncdist, xtable, reshape2, writexl)

# Define the necessary functions
compute_R_gamma <- function(f, gamma, r, alpha, beta) {
  # Handle boundary conditions
  if (f == 0 || gamma == 0) {
    return(0)
  }
  if (f == 1 && gamma == 1) {
    return(r)
  }
  
  # Compute the variance of p
  var_p <- (alpha * beta) / ((alpha + beta)^2 * (alpha + beta + 1))
  
  # Function to calculate the variance of the minimum of p and f
  var_tilde_p <- function(f, alpha, beta) {
    # Define the PDF of the Beta distribution
    beta_pdf <- function(p) dbeta(p, alpha, beta)
    
    # Define the CDF of the Beta distribution
    beta_cdf <- function(p) pbeta(p, alpha, beta)
    
    # First moment of tilde_p (E[tilde_p])
    first_moment <- integrate(function(p) {
      p * beta_pdf(p)
    }, lower = 0, upper = f)$value + f * (1 - beta_cdf(f))
    
    # Second moment of tilde_p (E[tilde_p^2])
    second_moment <- integrate(function(p) {
      p^2 * beta_pdf(p)
    }, lower = 0, upper = f)$value + f^2 * (1 - beta_cdf(f))
    
    # Variance of tilde_p
    second_moment - first_moment^2
  }
  
  # Compute the variance of tilde_p
  var_tilde_p_value <- var_tilde_p(f, alpha, beta)
  
  # Compute R_gamma(f, gamma)
  R_gamma_value <- r * gamma^2 * (var_tilde_p_value / var_p)
  
  return(R_gamma_value)
}

contract_market_profit <- function(f, gamma, c, r, alpha, beta) {
  term1 <- f * (1 - gamma * pbeta(f, alpha, beta))
  term2 <- gamma * integrate(function(p) p * dbeta(p, alpha, beta), lower = 0, upper = f)$value
  term3 <- compute_R_gamma(f, gamma, r, alpha, beta)
  return(term1 + term2 - term3 - c)
}

spot_market_profit <- function(c, mean_p, r) {
  return(mean_p - r - c)
}

# Function to find f_underline by solving the equality of profits
find_f_underline <- function(c, gamma, r, alpha, beta, mean_p) {
  # Define the function representing the difference in profits
  profit_difference <- function(f) {
    contract_market_profit(f, gamma, c, r, alpha, beta) - spot_market_profit(c, mean_p, r)
  }
  
  # Use uniroot to find the root of the profit difference function
  result <- tryCatch(
    uniroot(profit_difference, lower = mean_p - r, upper = mean_p)$root,
    error = function(e) NA
  )
  
  # Ensure the found f_underline is greater than or equal to E(p) - r
  if (!is.na(result) && result >= (mean_p - r)) {
    return(result)
  } else {
    return(NA)
  }
}

# Calculate the break-even investment cost c_break_even for a given gamma
find_c_break_even <- function(gamma, r, alpha, beta, mean_p) {
  tryCatch(
    uniroot(
      function(c) contract_market_profit(mean_p, gamma, c, r, alpha, beta),
      lower = 0, upper = 1  # Search interval for c, this could be adjusted depending on context
    )$root,
    error = function(e) NA
  )
}

# Calculate the highest investment cost c_bar(gamma) for which entry might be profitable
find_c_bar <- function(gamma, r, alpha, beta, mean_p) {
  # The highest investment cost such that the seller breaks even at f = E(p)
  find_c_break_even(gamma, r, alpha, beta, mean_p)
}

# Categorize entrants based on their costs
categorize_entry <- function(c, gamma, r, alpha, beta, mean_p) {
  # Calculate key thresholds
  f_lower_bound <- mean_p - r  # E(p) - r
  c_bar <- find_c_bar(gamma, r, alpha, beta, mean_p)
  
  # Check conditions for categorization
  if (c > c_bar || is.na(c_bar)) {
    return("No Entry (c > c_bar)")
  } else if (c <= f_lower_bound) {
    return("Low-Cost Entrant (c <= E(p) - r)")
  } else {
    return("Higher-Cost Entrant (c > E(p) - r)")
  }
}

# Initialize parameters
c_values <- seq(0, 1, by = 0.05)      # Example c values
gamma_values <- seq(0, 1, by = 0.1)  # Example gamma values
alpha <- 4                            # Alpha parameter of Beta distribution
beta <- 2                             # Beta parameter of Beta distribution
r <- 0.4                              # Risk premium
mean_p <- 0.6                         # E(p)

# Generate results for all combinations of gamma and c
entry_results <- data.frame()

for (gamma in gamma_values) {
  c_bar <- find_c_bar(gamma, r, alpha, beta, mean_p)  # Compute c_bar
  
  if (!is.na(c_bar)) {
    for (c in c_values) {
      # Compute specific f(gamma) using find_f_underline
      f_specific <- find_f_underline(c, gamma, r, alpha, beta, mean_p)
      
      # Compute E(p) - r (lower bound for low-cost entrants)
      lower_f_gamma <- mean_p - r
      
      # Compute profits in both markets
      profit_spot <- spot_market_profit(c, mean_p, r)
      profit_contract <- if (!is.na(f_specific)) {
        contract_market_profit(f_specific, gamma, c, r, alpha, beta)
      } else {
        NA
      }
      
      # Entrant Type Logic (with explicit NA checks)
      if (c > c_bar) {
        entrant_type <- "No Entry (c > c_bar)"
      } else if (c <= lower_f_gamma && !is.na(f_specific) && f_specific > c) {
        entrant_type <- "Low-Cost Entrant (c <= E(p) - r)"
      } else if (!is.na(profit_contract) && profit_contract >= c) {
        entrant_type <- "Higher-Cost Entrant (c > E(p) - r)"
      } else if (lower_f_gamma < c) {
        entrant_type <- "f(gamma) < c"
      } else {
        entrant_type <- "Undefined"
      }
      
      # Store results in entry_results
      entry_results <- rbind(
        entry_results,
        data.frame(
          gamma = gamma,
          c = c,
          c_bar = c_bar,
          f_specific = f_specific,
          lower_f_gamma = lower_f_gamma,
          profit_spot = profit_spot,
          profit_contract = profit_contract,
          profit_difference = profit_contract - profit_spot,
          c_bar_normalized = pmin(c / c_bar, 1),
          entrant_type = entrant_type
        )
      )
    }
  }
}

# Plot the results
ggplot(entry_results, aes(x = c_bar_normalized, y = f_specific, color = factor(gamma))) +
  geom_line(linewidth = 1) +
  geom_point(size = 2, alpha = 0.7) +
  labs(
    title = "Cumulative Supply G(c) vs Contract Prices f(gamma)",
    x = "Cumulative Supply G(c)",
    y = "Contract Price f(gamma)",
    color = "Gamma (Proportion of Opportunistic Buyers)"
  ) +
  theme_minimal() +
  scale_color_brewer(palette = "Dark2")

# Print the results
print(entry_results)

and the graph obtained does not look at all at the one shown above.

Any ideas how I can obtain more or less the first figure shown above, please? Thank you so much.

Michael

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.