Für Vorlesungen, bitte die Webseite verwenden. https://flavigny.de/lecture
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

105 linhas
3.3KB

  1. # Josua Kugler, Christian Merten
  2. # a) -----------------------------------------------------------------------
  3. midpoint <- function(f, a, b) (b-a) * f((a+b)/2)
  4. trapezoid <- function(f, a, b) (b-a) * (f(a) + f(b))/2
  5. # b) ----------------------------------------------------------------------
  6. nc_integrate <- function(f, lower, upper, n, rule) {
  7. xs <- seq(lower, upper, length.out=n+1)
  8. sum(rule(f, xs[-(n+1)], xs[-1]))
  9. }
  10. # c) ------------------------------------------------------------------------
  11. closeable_seq <- function(from, to, len, closed=TRUE) {
  12. if (closed) seq(from, to, length.out = len)
  13. else seq(from, to, length.out = len+2)[-c(1, len+2)]
  14. }
  15. newton_cotes <- function(coef, closed=TRUE) {
  16. m <- length(coef)
  17. w <- coef / sum(coef)
  18. function(f, a, b) {
  19. t <- mapply(closeable_seq, a, b, len=m, closed=closed)
  20. (b-a) * colSums(w*matrix(f(t), ncol=length(a)))
  21. }
  22. }
  23. # d) ------------------------------------------------------------------------
  24. # some objects for param_fun-list
  25. sin1x <- function(x) {
  26. y <- suppressWarnings(sin(1/x))
  27. y[is.na(y)] <- 0
  28. y
  29. }
  30. set.seed(0)
  31. x <- c(0:1, runif(5))
  32. y <- runif(7)
  33. # list of functions with integral interval
  34. param_fun <- list(
  35. poly = list(f = function(x) x^4 - x^3 - 3*x^2 + x + 2, lower = 0, upper = 2),
  36. sin1x = list(f = sin1x, lower = 0, upper = 1),
  37. lin = list(f = approxfun(x, y), lower = 0, upper = 1),
  38. spline = list(f = splinefun(x, y), lower = 0, upper = 1)
  39. )
  40. # true values of integrals
  41. true <- c(
  42. poly = 0.4,
  43. sin1x = 0.504067061906928,
  44. lin = 0.472878602164825,
  45. spline = 0.97236924451286)
  46. # options for creating integral-rules
  47. param_rule <- list(
  48. midpoint = list(coef = 1, closed=FALSE),
  49. trapezoid = list(coef = c(1,1), closed=TRUE),
  50. simpson = list(coef = c(1,4,1), closed=TRUE),
  51. boole = list(coef = c(7,32,12,32,7), closed=TRUE),
  52. open5 = list(coef = c(611, -453, 562, 562, -453, 611), closed=FALSE)
  53. )
  54. # how many function evaluations are allowed
  55. param_n <- 5*(2:20)
  56. library(tidyverse)
  57. param <- as_tibble(
  58. expand.grid(n = param_n,
  59. fun_name = names(param_fun),
  60. rule_name = names(param_rule),
  61. stringsAsFactors=FALSE))
  62. nc_rules <- sapply(param_rule, do.call, what=newton_cotes)
  63. # run nc_integrate with given options
  64. call_nc <- function(n, fun_name, rule_name) {
  65. opts <- param_fun[[fun_name]]
  66. opts$rule = nc_rules[[rule_name]]
  67. # to make things fair:
  68. # a rule which evaluates f at m points may only be called n/m times
  69. opts$n = round(n / length(param_rule[[rule_name]]$coef))
  70. do.call(nc_integrate, opts)
  71. }
  72. param %>% rowwise() %>%
  73. mutate(value=nc_integrate(param_fun[[fun_name]]$f,
  74. lower = param_fun[[fun_name]]$lower,
  75. upper = param_fun[[fun_name]]$upper,
  76. n = n,
  77. rule = nc_rules[[rule_name]]),
  78. true=true[[fun_name]],
  79. error=abs(true-value)) -> res
  80. # plot results
  81. plots <- lapply(names(param_fun), function(nm)
  82. res %>%
  83. filter(fun_name == nm) %>%
  84. ggplot(aes(x = n, y = error, color = rule_name)) +
  85. scale_y_log10() +
  86. geom_line() + geom_point() + labs(title = nm)
  87. )
  88. gridExtra::grid.arrange(grobs = plots, nrow=2)