diff --git a/NAMESPACE b/NAMESPACE
index 3212ce0a81f169d138bf7a06ed94023585f954c7..05e80c9ed5aa0658d960dda9c837755db358846a 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -42,6 +42,7 @@ exportMethods(ageShift)
 exportMethods(ages)
 exportMethods(baseTable)
 exportMethods(baseYear)
+exportMethods(calculateImprovements)
 exportMethods(deathProbabilities)
 exportMethods(getCohortTable)
 exportMethods(getOmega)
diff --git a/R/deathProbabilities.R b/R/deathProbabilities.R
index c172cfa5fdbcd76fe7ec9a563709274d916ad4f8..92ff4da3280046de905ecc50c30a8c7a53c4e9f2 100644
--- a/R/deathProbabilities.R
+++ b/R/deathProbabilities.R
@@ -65,8 +65,8 @@ setMethod("deathProbabilities","mortalityTable.trendProjection",
 setMethod("deathProbabilities","mortalityTable.improvementFactors",
           function(object,  ..., YOB = 1975) {
               qx = object@deathProbs * (1 + object@loading);
-              finalqx = (1 - object@improvement)^(YOB + 0:(length(qx) - 1) - object@baseYear) * qx;
-              object@modification(finalqx)
+              impr = calculateImprovements(object, ..., YOB = YOB)
+              object@modification(impr * qx)
           })
 
 #' @describeIn deathProbabilities Return the (cohort) death probabilities of the
diff --git a/R/mortalityTable.improvementFactors.R b/R/mortalityTable.improvementFactors.R
index 80d599f5348149d929c90b8bb819a9633420d628..bf456d2e4c1ace4fa89cb506cd21e3857d7aae85 100644
--- a/R/mortalityTable.improvementFactors.R
+++ b/R/mortalityTable.improvementFactors.R
@@ -1,6 +1,8 @@
 #' @include mortalityTable.R mortalityTable.period.R
 NULL
 
+setClassUnion("vectorOrMatrix", c("numeric", "matrix"))
+
 #' Class mortalityTable.improvementFactors - Cohort life table with improvement
 #' factors
 #'
@@ -33,7 +35,7 @@ mortalityTable.improvementFactors = setClass(
     "mortalityTable.improvementFactors",
     slots = list(
         baseYear = "numeric",
-        improvement = "numeric"
+        improvement = "vectorOrMatrix"
     ),
     prototype = list(
         baseYear = 2012,
@@ -41,3 +43,87 @@ mortalityTable.improvementFactors = setClass(
     ),
     contains = "mortalityTable.period"
 )
+
+
+
+#' Calculate the improvement factors for the given birth-year and the
+#' \code{\linkS4class{mortalityTable.improvementsFactors}} object
+#'
+#' @param object A pension table object (instance of a \code{\linkS4class{mortalityTable.improvementFactors}} class)
+#' @param ... Currently unused
+#' @param Period Observation period (either \code{Period} or \code{YOB} should be given)
+#' @param YOB Year of birth (either \code{Period} or \code{YOB} should be given)
+#'
+#' @examples
+#' pensionTables.load("USA_PensionPlan_RP2014")
+#' calculateImprovements(RP2014.male, YOB = 2017)
+#'
+#' @exportMethod calculateImprovements
+setGeneric("calculateImprovements", function(object, ...) standardGeneric("calculateImprovements"));
+
+#' @describeIn calculateImprovements Calculate the total mortality improvement
+#' factors relative to the base year for the given birth-year and the
+#' \code{\linkS4class{mortalityTable.improvementsFactors}} object
+setMethod("calculateImprovements", "mortalityTable.improvementFactors",
+    function(object, ..., Period = NULL, YOB = 1982) {
+        if (is.array(object@improvement)) {
+            # All years outside the observation interval use the improvements
+            # at the boundaries
+            minObservation = strtoi(head(colnames(object@improvement), 1))
+            maxObservation = strtoi(tail(colnames(object@improvement), 1))
+
+            if (!missing(Period) && !is.null(Period)) {
+                # Period improvements:
+                if (Period == object@baseYear) {
+                    ags = ages(object)
+                    improvements = rep(1, length(ags))
+                    names(improvements) = ags
+                } else if (Period < object@baseYear) {
+                    # Past mortalities
+                    years = Period:(object@baseYear - 1)
+                    years = sapply(years, function(x) { max(x, minObservation) } )
+                    imprY = 1 - object@improvement[,as.character(years), drop = FALSE]
+                    improvements = 1 / apply(imprY, 1, prod)
+                } else {
+                    # Projection into the future
+                    years = object@baseYear:(Period - 1)
+                    years = sapply(years, function(x) { min(x, maxObservation) } )
+                    imprY = 1 - object@improvement[,as.character(years), drop = FALSE]
+                    improvements = apply(imprY, 1, prod)
+                }
+            } else {
+                # Generational improvements
+                ags = ages(object)
+                # For each age, determine the year and the improvement factors
+                # until/from the base year and multiply them
+                improvements = sapply(ags, function(a) {
+                    yr = YOB + a
+                    if (yr == object@baseYear) {
+                        1
+                    } else if (yr < object@baseYear) {
+                        # Past mortalities
+                        years = yr:(object@baseYear - 1)
+                        years = sapply(years, function(x) { max(x, minObservation) } )
+                        imprY = 1 - object@improvement[as.character(a), as.character(years)]
+                        1 / prod(imprY)
+                    } else {
+                        # Projection into the future
+                        years = object@baseYear:(yr - 1)
+                        years = sapply(years, function(x) { min(x, maxObservation) } )
+                        imprY = 1 - object@improvement[as.character(a), as.character(years)]
+                        prod(imprY)
+                    }
+                })
+                names(improvements) = ags
+            }
+        } else {
+            if (!missing(Period) && !is.null(Period)) {
+                improvements = (1 - object@improvement) ^ (Period - object@baseYear);
+            } else {
+                improvements = (1 - object@improvement) ^ (YOB + ages(object) - object@baseYear);
+            }
+        }
+        improvements
+    }
+)
+
diff --git a/R/periodDeathProbabilities.R b/R/periodDeathProbabilities.R
index 3423faa8eac977e94a6e33f606e535aff4efae33..6a8a0c29600b63aea2240113d78714c9e9d72112 100644
--- a/R/periodDeathProbabilities.R
+++ b/R/periodDeathProbabilities.R
@@ -54,8 +54,8 @@ setMethod("periodDeathProbabilities", "mortalityTable.trendProjection",
 setMethod("periodDeathProbabilities", "mortalityTable.improvementFactors",
           function (object, ..., Period = 1975) {
               qx = object@deathProbs * (1 + object@loading);
-              finalqx = (1 - object@improvement) ^ (Period - object@baseYear) * qx;
-              object@modification(finalqx)
+              impr = calculateImprovements(object, ..., Period = Period)
+              object@modification(qx * impr)
           })
 
 #' @describeIn periodDeathProbabilities Return the (period) death probabilities
diff --git a/inst/extdata/PensionTables_USA_PensionPlan_RP2014.R b/inst/extdata/PensionTables_USA_PensionPlan_RP2014.R
new file mode 100644
index 0000000000000000000000000000000000000000..0b86d76908f14a7821372edb4ea60cff990bfcb9
--- /dev/null
+++ b/inst/extdata/PensionTables_USA_PensionPlan_RP2014.R
@@ -0,0 +1,195 @@
+#' @import MortalityTables
+NULL
+
+stopifnot(require(methods), require(utils), require(MortalityTables)) # MortalityTable classes; new; Excel reader
+
+my.natrim <- function(v, ...) {
+    # Add a NA at the beginning and end, so the first and last entry of the rle
+    # call will always be for a NA => Use them to call head and tail accordingly:
+    vv = c(NA, v, NA);
+    r = rle(!is.na(vv));
+    tail(head(vv, -tail(r$lengths, 1)), -head(r$lengths, 1))
+}
+
+###############################################################################
+# USA: RP2014 pension plan table with MP2014 mortality improvement factors
+###############################################################################
+
+RP2014.data = utils::read.csv(
+    system.file("extdata", "USA_PensionPlans_RP2014.csv", package = "MortalityTables"),
+    skip = 4,
+    header = FALSE,
+    col.names = c(
+        "age",
+        "qax", "qpx", "qix",
+        "qay", "qpy", "qiy",
+        "SPACER",
+        "qax_blue", "qpx_blue",
+        "qay_blue", "qpy_blue",
+        "SPACER",
+        "qax_white", "qpx_white",
+        "qay_white", "qpy_white",
+        "SPACER",
+        "age_young", "qx_young", "qy_young")
+    #, colClasses = c(age = "numeric", qax = "numeric", qpx = "numeric", qix = "numeric", qay = "numeric", qpy = "numeric", qiy = "numeric")
+);
+
+RP2014.readImprovements = function(file) {
+    data = as.matrix(utils::read.csv(
+        system.file("extdata", "USA_PensionPlans_MP2014_Male.csv", package = "MortalityTables"),
+        skip = 1,
+        check.names = FALSE,
+        header = TRUE,
+        row.names = 1
+    ))
+    cn = colnames(data)
+    lastyear = tail(cn,1)
+    lastyear = substr(lastyear, 1, nchar(lastyear) - 1);
+    colnames(data) = c(head(cn, -1), lastyear)
+    bel20 = data["≤ 20",];
+    young = matrix(bel20, ncol = length(bel20), nrow = 21, byrow = TRUE, dimnames = list(0:20, colnames(data)))
+    rbind(young, data[-1,])
+}
+
+RP2014.improvement.male = RP2014.readImprovements("USA_PensionPlans_MP2014_Male.csv");
+RP2014.improvement.female = RP2014.readImprovements("USA_PensionPlans_MP2014_Female.csv");
+
+
+nameRP14 = function(name = "", desc = "") {
+    paste("RP2014", name, ", ", desc, sep = "")
+}
+
+tableRP14 = function(name, data = data, agevar = "age", probvar, improvement = NULL, ..., baseyear = 2014) {
+    if (is.null(improvement)) {
+        mortalityTable.period(
+            name = name, ages = data[[agevar]], baseYear = baseyear,
+            deathProbs = data[[probvar]], ...)
+    } else {
+        mortalityTable.improvementFactors(
+            name = name, ages = data[[agevar]], baseYear = baseyear,
+            deathProbs = data[[probvar]], improvement = improvement, ...)
+    }
+}
+
+RP2014.zeroes = mortalityTable.zeroes(name = "No transition", ages = RP2014.data[["age"]])
+
+
+################################################################################
+# Total Dataset (RP-2014 with MP-2014 improvements)
+################################################################################
+name = "";
+
+RP2014.male = pensionTable(
+    name = nameRP14(desc = "male"),
+    baseYear = 2014,
+    qx =  tableRP14(nameRP14(name, "qax, active males"), RP2014.data, "age", "qax", improvement = RP2014.improvement.male),
+    # The RP2014 table does not contain any invalidity probabilities
+    ix = RP2014.zeroes,
+    qgx = RP2014.zeroes,
+    qix = tableRP14(nameRP14(name, "qix, disabled males"), RP2014.data, "age", "qix", improvement = RP2014.improvement.male),
+    rx =  RP2014.zeroes,
+    apx = RP2014.zeroes,
+    apix = RP2014.zeroes,
+    qpx = tableRP14(nameRP14(name, "qpx, retired males"), RP2014.data, "age", "qpx", improvement = RP2014.improvement.male),
+    hx =  RP2014.zeroes,
+    qwy = RP2014.zeroes,
+    yx =  RP2014.zeroes
+)
+RP2014.female = pensionTable(
+    name = nameRP14(desc = "female"),
+    baseYear = 2014,
+    qx =  tableRP14(nameRP14(name, "qay, active females"), RP2014.data, "age", "qay", improvement = RP2014.improvement.female),
+    # The RP2014 table does not contain any invalidity probabilities
+    ix = RP2014.zeroes,
+    qgx = RP2014.zeroes,
+    qix = tableRP14(nameRP14(name, "qiy, disabled females"), RP2014.data, "age", "qiy", improvement = RP2014.improvement.female),
+    rx =  RP2014.zeroes,
+    apx = RP2014.zeroes,
+    apix = RP2014.zeroes,
+    qpx = tableRP14(nameRP14(name, "qpy, retired females"), RP2014.data, "age", "qpy", improvement = RP2014.improvement.female),
+    hx =  RP2014.zeroes,
+    qwy = RP2014.zeroes,
+    yx =  RP2014.zeroes
+)
+
+
+################################################################################
+# White collar dataset (RP-2014 with MP-2014 improvements)
+################################################################################
+name = "White Collar";
+
+RP2014.male.whitecollar = pensionTable(
+    name = nameRP14(desc = "male"),
+    baseYear = 2014,
+    qx =  tableRP14(nameRP14(name, "qax, active males"), RP2014.data, "age", "qax_white", improvement = RP2014.improvement.male),
+    # The RP2014 table does not contain any invalidity probabilities
+    ix = RP2014.zeroes,
+    qgx = RP2014.zeroes,
+    qix = tableRP14(nameRP14(name, "qix, disabled males"), RP2014.data, "age", "qix", improvement = RP2014.improvement.male),
+    rx =  RP2014.zeroes,
+    apx = RP2014.zeroes,
+    apix = RP2014.zeroes,
+    qpx = tableRP14(nameRP14(name, "qpx, retired males"), RP2014.data, "age", "qpx_white", improvement = RP2014.improvement.male),
+    hx =  RP2014.zeroes,
+    qwy = RP2014.zeroes,
+    yx =  RP2014.zeroes
+)
+RP2014.female.whitecollar = pensionTable(
+    name = nameRP14(desc = "female"),
+    baseYear = 2014,
+    qx =  tableRP14(nameRP14(name, "qay, active females"), RP2014.data, "age", "qay_white", improvement = RP2014.improvement.female),
+    # The RP2014 table does not contain any invalidity probabilities
+    ix = RP2014.zeroes,
+    qgx = RP2014.zeroes,
+    qix = tableRP14(nameRP14(name, "qiy, disabled females"), RP2014.data, "age", "qiy", improvement = RP2014.improvement.female),
+    rx =  RP2014.zeroes,
+    apx = RP2014.zeroes,
+    apix = RP2014.zeroes,
+    qpx = tableRP14(nameRP14(name, "qpy, retired females"), RP2014.data, "age", "qpy_white", improvement = RP2014.improvement.female),
+    hx =  RP2014.zeroes,
+    qwy = RP2014.zeroes,
+    yx =  RP2014.zeroes
+)
+
+
+################################################################################
+# Blue collar dataset (RP-2014 with MP-2014 improvements)
+################################################################################
+name = "Blue Collar";
+
+RP2014.male.bluecollar = pensionTable(
+    name = nameRP14(desc = "male"),
+    baseYear = 2014,
+    qx =  tableRP14(nameRP14(name, "qax, active males"), RP2014.data, "age", "qax_blue", improvement = RP2014.improvement.male),
+    # The RP2014 table does not contain any invalidity probabilities
+    ix = RP2014.zeroes,
+    qgx = RP2014.zeroes,
+    qix = tableRP14(nameRP14(name, "qix, disabled males"), RP2014.data, "age", "qix", improvement = RP2014.improvement.male),
+    rx =  RP2014.zeroes,
+    apx = RP2014.zeroes,
+    apix = RP2014.zeroes,
+    qpx = tableRP14(nameRP14(name, "qpx, retired males"), RP2014.data, "age", "qpx_blue", improvement = RP2014.improvement.male),
+    hx =  RP2014.zeroes,
+    qwy = RP2014.zeroes,
+    yx =  RP2014.zeroes
+)
+RP2014.female.bluecollar = pensionTable(
+    name = nameRP14(desc = "female"),
+    baseYear = 2014,
+    qx =  tableRP14(nameRP14(name, "qay, active females"), RP2014.data, "age", "qay_blue", improvement = RP2014.improvement.female),
+    # The RP2014 table does not contain any invalidity probabilities
+    ix = RP2014.zeroes,
+    qgx = RP2014.zeroes,
+    qix = tableRP14(nameRP14(name, "qiy, disabled females"), RP2014.data, "age", "qix", improvement = RP2014.improvement.female),
+    rx =  RP2014.zeroes,
+    apx = RP2014.zeroes,
+    apix = RP2014.zeroes,
+    qpx = tableRP14(nameRP14(name, "qpy, retired females"), RP2014.data, "age", "qpy_blue", improvement = RP2014.improvement.female),
+    hx =  RP2014.zeroes,
+    qwy = RP2014.zeroes,
+    yx =  RP2014.zeroes
+)
+
+
+rm(RP2014.data, tableRP14, nameRP14, RP2014.readImprovements, RP2014.zeroes)
+
diff --git a/inst/extdata/PensionTables_USA_PensionPlans.R b/inst/extdata/PensionTables_USA_PensionPlans.R
new file mode 100644
index 0000000000000000000000000000000000000000..24ad28e7ebfb45cebebcdbe7e129c0fc48d92fc7
--- /dev/null
+++ b/inst/extdata/PensionTables_USA_PensionPlans.R
@@ -0,0 +1,3 @@
+stopifnot(require(methods), require(utils), require(MortalityTables))
+
+pensionTables.load("USA_PensionPlan_*")
diff --git a/man/calculateImprovements.Rd b/man/calculateImprovements.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..56da9d3cafe13219688588509e285816857b3c23
--- /dev/null
+++ b/man/calculateImprovements.Rd
@@ -0,0 +1,39 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/mortalityTable.improvementFactors.R
+\docType{methods}
+\name{calculateImprovements}
+\alias{calculateImprovements}
+\alias{calculateImprovements,mortalityTable.improvementFactors-method}
+\title{Calculate the improvement factors for the given birth-year and the
+\code{\linkS4class{mortalityTable.improvementsFactors}} object}
+\usage{
+calculateImprovements(object, ...)
+
+\S4method{calculateImprovements}{mortalityTable.improvementFactors}(object, ...,
+  Period = NULL, YOB = 1982)
+}
+\arguments{
+\item{object}{A pension table object (instance of a \code{\linkS4class{mortalityTable.improvementFactors}} class)}
+
+\item{...}{Currently unused}
+
+\item{Period}{Observation period (either \code{Period} or \code{YOB} should be given)}
+
+\item{YOB}{Year of birth (either \code{Period} or \code{YOB} should be given)}
+}
+\description{
+Calculate the improvement factors for the given birth-year and the
+\code{\linkS4class{mortalityTable.improvementsFactors}} object
+}
+\section{Methods (by class)}{
+\itemize{
+\item \code{mortalityTable.improvementFactors}: Calculate the total mortality improvement
+factors relative to the base year for the given birth-year and the
+\code{\linkS4class{mortalityTable.improvementsFactors}} object
+}}
+
+\examples{
+pensionTables.load("USA_PensionPlan_RP2014")
+calculateImprovements(RP2014.male, YOB = 2017)
+
+}