diff --git a/README.md b/README.md
index 2a8ac55..4433e10 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-This package implements the models of [Shelegia and Motta (2021)](shelegia_motta_2021.pdf).
+This package implements the models of [Shelegia and Motta (2021)](resources/shelegia_motta_2021.pdf).
![GitHub](https://img.shields.io/github/license/manuelbieri/shelegia_motta_2021)
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/Shelegia-Motta-2021)
@@ -94,14 +94,5 @@ Generate api-documentation with the following command:
pdoc -o ./docs Shelegia_Motta_2021 --docformat "numpy" --math
```
-#### Dependencies
-
-| Package | Version | Annotation |
-|:-----------|:---------|:------------------------------------------------|
-| matplotlib | 3.4.3 | Always needed (includes numpy) |
-| jupyter | 1.0.0 | Just for the demonstration in demo.ipynb |
-| pdoc | 8.0.1 | Only to generate the documentation from scratch |
-
-
#### Additional Notes
-For further information about the coordinates used in the code, see dev_notes.md.
+For further information about the coordinates used in the code, see resources/dev_notes.md.
diff --git a/Shelegia_Motta_2021/IModel.py b/Shelegia_Motta_2021/IModel.py
index b967082..09c8ccb 100644
--- a/Shelegia_Motta_2021/IModel.py
+++ b/Shelegia_Motta_2021/IModel.py
@@ -159,7 +159,7 @@ def get_optimal_choice(self, A: float, F: float) -> Dict[str, str]:
pass
@abc.abstractmethod
- def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes:
+ def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None, **kwargs) -> matplotlib.axes.Axes:
"""
Plots the best answers of the incumbent to all possible actions of the entrant.
@@ -167,6 +167,10 @@ def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None) -> matp
----------
axis : matplotlib.axes.Axes
Axis to draw the plot on. (optional)
+ **kwargs
+ Optional key word arguments for the best answers plot.
+ - title: title on top of the plot, instead of the default title.
+ - options_legend: If true, an additional legend, explaining the options of the entrant and the incumbent, will be added to the plot.
Returns
-------
@@ -176,7 +180,7 @@ def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None) -> matp
pass
@abc.abstractmethod
- def plot_equilibrium(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes:
+ def plot_equilibrium(self, axis: matplotlib.axes.Axes = None, **kwargs) -> matplotlib.axes.Axes:
"""
Plots the equilibrium path based on the choices of the entrant and incumbent.
@@ -184,6 +188,10 @@ def plot_equilibrium(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes
----------
axis : matplotlib.axes.Axes
Axis to draw the plot on. (optional)
+ **kwargs
+ Optional key word arguments for the equilibrium plot.
+ - title: title on top of the plot, instead of the default title.
+ - options_legend: If true, an additional legend, explaining the options of the entrant and the incumbent, will be added to the plot.
Returns
-------
diff --git a/Shelegia_Motta_2021/Models.py b/Shelegia_Motta_2021/Models.py
index 5f57d81..d8365db 100644
--- a/Shelegia_Motta_2021/Models.py
+++ b/Shelegia_Motta_2021/Models.py
@@ -1,4 +1,4 @@
-from typing import Dict, List, Tuple, Literal
+from typing import Dict, List, Tuple, Literal, Final
import matplotlib.axes
import matplotlib.pyplot as plt
@@ -15,7 +15,7 @@ class BaseModel(Shelegia_Motta_2021.IModel):
There are two players in our base model: The Incumbent, which sells the primary product, denoted by Ip, and a start-up, called the Entrant, which sells a product Ec complementary to Ip. (One may think of Ip as a platform, and Ec as a service or product which can be accessed through the platform.) We are interested in studying the choice of E between developing a substitute to Ip, denoted by Ep, or another complement to Ip, denoted by Ẽc and the choice of I between copying E’s original complementary product Ec by creating a perfect substitute Ic, or not. Since E may not have enough assets to cover the development cost of its second product, copying its current product will affect the entrant’s ability to obtain funding for the development. We shall show that the incumbent has a strategic incentive to copy when the entrant plans to compete, and to abstain from copying when it plans to create another complement.
"""
- tolerance: float = 10 ** (-8)
+ TOLERANCE: Final[float] = 10 ** (-8)
"""Tolerance for the comparison of two floating numbers."""
def __init__(self, u: float = 1, B: float = 0.5, small_delta: float = 0.5, delta: float = 0.51,
@@ -235,7 +235,7 @@ def _plot(self, coordinates: List[List[Tuple[float, float]]], labels: List[str],
Axis containing the plot.
"""
if axis is None:
- fig, axis = plt.subplots()
+ figure, axis = plt.subplots()
self._draw_thresholds(axis)
for i, coordinates in enumerate(coordinates):
@@ -243,18 +243,19 @@ def _plot(self, coordinates: List[List[Tuple[float, float]]], labels: List[str],
axis.add_patch(poly)
axis.legend(bbox_to_anchor=(1.3, 1), loc="upper left")
+ if kwargs.get('options_legend', False):
+ axis.text(-0.05, -0.4, self._create_options_legend(), verticalalignment='top')
BaseModel._set_axis_labels(axis, title=kwargs.get('title', ''),
x_label=kwargs.get('xlabel', 'Assets of the entrant'),
y_label=kwargs.get('ylabel', 'Fixed costs of copying for the incumbent'))
BaseModel._set_axis(axis)
- plt.show()
return axis
- def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes:
+ def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None, **kwargs) -> matplotlib.axes.Axes:
poly_coordinates: List[List[Tuple[float, float]]] = self._get_incumbent_best_answer_coordinates()
poly_labels: List[str] = self._get_incumbent_best_answer_labels()
- axis: matplotlib.axes.Axes = self._plot(title="Best Answers of the incumbent to the choices of the entrant",
- coordinates=poly_coordinates, labels=poly_labels, axis=axis)
+ axis: matplotlib.axes.Axes = self._plot(title=kwargs.get("title", "Best Answers of the incumbent to the choices of the entrant"),
+ coordinates=poly_coordinates, labels=poly_labels, axis=axis, options_legend=kwargs.get('options_legend', False))
return axis
def _create_choice_answer_label(self, entrant: Literal["complement", "substitute", "indifferent"],
@@ -267,7 +268,7 @@ def _get_incumbent_best_answer_labels(self) -> List[str]:
"""
Returns a list containing the labels for the squares in the plot of the best answers of the incumbent to the choice of the entrant.
- For the order of the labels refer to the file devnotes.md.
+ For the order of the labels refer to the file resources/dev_notes.md.
Returns
-------
@@ -298,7 +299,7 @@ def _get_incumbent_best_answer_coordinates(self) -> List[List[Tuple[float, float
"""
Returns a list containing the coordinates for the squares in the plot of the best answers of the incumbent to the choice of the entrant.
- For the order of the squares refer to the file devnotes.md.
+ For the order of the squares refer to the file resources/dev_notes.md.
Returns
-------
@@ -330,18 +331,18 @@ def _get_incumbent_best_answer_coordinates(self) -> List[List[Tuple[float, float
(x_max, y_max), (0, y_max),
(0, self._copying_fixed_costs['F(YN)s']), (self._assets['A-s'], self._copying_fixed_costs['F(YN)s'])]]
- def plot_equilibrium(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes:
+ def plot_equilibrium(self, axis: matplotlib.axes.Axes = None, **kwargs) -> matplotlib.axes.Axes:
poly_coordinates: List[List[Tuple[float, float]]] = self._get_equilibrium_coordinates()
poly_labels: List[str] = self._get_equilibrium_labels()
- axis: matplotlib.axes.Axes = self._plot(title='Equilibrium Path in the base Model',
- coordinates=poly_coordinates, labels=poly_labels, axis=axis)
+ axis: matplotlib.axes.Axes = self._plot(title=kwargs.get("title", "Equilibrium Path"),
+ coordinates=poly_coordinates, labels=poly_labels, axis=axis, options_legend=kwargs.get('options_legend', False))
return axis
def _get_equilibrium_labels(self) -> List[str]:
"""
Returns a list containing the labels for the squares in the plot of the equilibrium path.
- For the order of the squares refer to the file devnotes.md.
+ For the order of the squares refer to the file resources/dev_notes.md.
Returns
-------
@@ -362,7 +363,7 @@ def _get_equilibrium_coordinates(self) -> List[List[Tuple[float, float]]]:
"""
Returns a list containing the coordinates for the squares in the plot of the equilibrium path.
- For the order of the squares refer to the file devnotes.md.
+ For the order of the squares refer to the file resources/dev_notes.md.
Returns
-------
@@ -388,7 +389,7 @@ def _get_equilibrium_coordinates(self) -> List[List[Tuple[float, float]]]:
def plot_payoffs(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes:
if axis is None:
- fig, axis = plt.subplots()
+ figure, axis = plt.subplots()
index = arange(0, len(self._payoffs) * 2, 2)
bar_width = 0.35
opacity = 0.8
@@ -517,7 +518,7 @@ def _draw_thresholds(self, axis: matplotlib.axes.Axes) -> None:
self._draw_horizontal_line_with_label(axis, y=self._copying_fixed_costs['F(YN)s'], label="$F^{YN}_S$")
self._draw_horizontal_line_with_label(axis, y=self._copying_fixed_costs['F(YY)c'], label="$F^{YY}_C$")
- if abs(self._copying_fixed_costs['F(YY)s'] - self._copying_fixed_costs['F(YN)c']) < BaseModel.tolerance:
+ if abs(self._copying_fixed_costs['F(YY)s'] - self._copying_fixed_costs['F(YN)c']) < BaseModel.TOLERANCE:
self._draw_horizontal_line_with_label(axis, y=self._copying_fixed_costs['F(YY)s'],
label="$F^{YY}_S=F^{YN}_C$")
else:
@@ -564,6 +565,19 @@ def _draw_vertical_line_with_label(self, axis: matplotlib.axes.Axes, x: float, l
if label is not None:
axis.text(x, label_y, label)
+ def _create_options_legend(self, latex: bool = True) -> str:
+ space: str = "$\quad$" if latex else "\t"
+ return "Options of the entrant:\n" + \
+ space + self.ENTRANT_CHOICES['complement'] + ": Tries to develop an additional complementary product to a primary product.\n" + \
+ space + self.ENTRANT_CHOICES['substitute'] + ": Tries to develop an substitute to the primary product of the incumbent.\n" + \
+ space + self.ENTRANT_CHOICES['indifferent'] + " : Indifferent between the options mentioned above.\n" + \
+ "Options of the incumbent:\n" + \
+ space + self.INCUMBENT_CHOICES['copy'] + " : Tries to develop an additional complementary product to a primary product.\n" + \
+ space + self.INCUMBENT_CHOICES['refrain'] + " : Tries to develop an additional complementary product to a primary product.\n" + \
+ "Outcomes of the development:\n" + \
+ space + self.DEVELOPMENT_OUTCOME['success'] + " : The additional product can be developed, since the entrant has sufficient assets.\n" + \
+ space + self.DEVELOPMENT_OUTCOME['failure'] + " : The additional product can not be developed, since the entrant has not enough assets."
+
@staticmethod
def _get_color(i: int) -> str:
"""
@@ -793,8 +807,8 @@ def __init__(self, u: float = 1, B: float = 0.5, small_delta: float = 0.5, delta
"""
super(UnobservableModel, self).__init__(u=u, B=B, small_delta=small_delta, delta=delta, K=K, beta=beta)
- def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes:
- return self.plot_equilibrium(axis=axis)
+ def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None, **kwargs) -> matplotlib.axes.Axes:
+ return self.plot_equilibrium(axis=axis, kwargs=kwargs)
def _create_choice_answer_label(self, entrant: Literal["complement", "substitute", "indifferent"],
incumbent: Literal["copy", "refrain"],
@@ -806,7 +820,7 @@ def _get_equilibrium_labels(self) -> List[str]:
"""
Returns a list containing the labels for the squares in the plot of the equilibrium path.
- For the order of the squares refer to the file devnotes.md.
+ For the order of the squares refer to the file resources/dev_notes.md.
Returns
-------
@@ -823,6 +837,13 @@ def _get_equilibrium_labels(self) -> List[str]:
self._create_choice_answer_label(entrant="substitute", incumbent="refrain", development="success")
]
+ def get_optimal_choice(self, A: float, F: float) -> Dict[str, str]:
+ result: Dict = super().get_optimal_choice(A, F)
+ # adjust the different choices in area three -> since the kill zone does not exist in this model.
+ if result["entrant"] == self.ENTRANT_CHOICES["complement"]:
+ result = {"entrant": self.ENTRANT_CHOICES["substitute"], "incumbent": self.INCUMBENT_CHOICES["copy"], "development": self.DEVELOPMENT_OUTCOME["failure"]}
+ return result
+
class AcquisitionModel(BargainingPowerModel):
"""
@@ -864,6 +885,6 @@ def get_copying_fixed_costs_values(self) -> Dict[str, float]:
if __name__ == '__main__':
- base_model = UnobservableModel(beta=0.6)
- base_model.plot_equilibrium()
- print(base_model)
+ bargaining_power_model = Shelegia_Motta_2021.BargainingPowerModel(beta=0.6)
+ bargaining_power_model.plot_equilibrium()
+ plt.show()
diff --git a/Shelegia_Motta_2021_Test/ModelTest.py b/Shelegia_Motta_2021_Test/ModelTest.py
index 45c4711..1bb88e6 100644
--- a/Shelegia_Motta_2021_Test/ModelTest.py
+++ b/Shelegia_Motta_2021_Test/ModelTest.py
@@ -2,10 +2,13 @@
from typing import Dict
from Shelegia_Motta_2021.IModel import IModel
-from Shelegia_Motta_2021.Models import BaseModel
+from Shelegia_Motta_2021.Models import BaseModel, BargainingPowerModel, UnobservableModel
class BaseModelTest(unittest.TestCase):
+ """
+ See dev_notes.md for the enumeration of the areas used in the testcases.
+ """
@staticmethod
def setUpModel() -> IModel:
return BaseModel()
@@ -16,6 +19,26 @@ def setUp(self) -> None:
self.assets: Dict[str, float] = self.model.get_asset_values()
self.utility: Dict[str, Dict[str, float]] = self.model.get_payoffs()
+ def assert_area_one(self, choice: Dict[str, str]):
+ self.assertEqual(choice["entrant"], self.model.ENTRANT_CHOICES["indifferent"])
+ self.assertEqual(choice["incumbent"], self.model.INCUMBENT_CHOICES["copy"])
+ self.assertEqual(choice["development"], self.model.DEVELOPMENT_OUTCOME["failure"])
+
+ def assert_area_two(self, choice: Dict[str, str]):
+ self.assertEqual(choice["entrant"], self.model.ENTRANT_CHOICES["substitute"])
+ self.assertEqual(choice["incumbent"], self.model.INCUMBENT_CHOICES["copy"])
+ self.assertEqual(choice["development"], self.model.DEVELOPMENT_OUTCOME["success"])
+
+ def assert_area_three(self, choice: Dict[str, str]):
+ self.assertEqual(choice["entrant"], self.model.ENTRANT_CHOICES["complement"])
+ self.assertEqual(choice["incumbent"], self.model.INCUMBENT_CHOICES["refrain"])
+ self.assertEqual(choice["development"], self.model.DEVELOPMENT_OUTCOME["success"])
+
+ def assert_area_four(self, choice: Dict[str, str]):
+ self.assertEqual(choice["entrant"], self.model.ENTRANT_CHOICES["substitute"])
+ self.assertEqual(choice["incumbent"], self.model.INCUMBENT_CHOICES["refrain"])
+ self.assertEqual(choice["development"], self.model.DEVELOPMENT_OUTCOME["success"])
+
def test_invalid_A1b(self):
self.assertRaises(AssertionError, BaseModel, small_delta=0.2)
self.assertRaises(AssertionError, BaseModel, delta=0.2)
@@ -25,24 +48,82 @@ def test_invalid_A2(self):
def test_path_indifferent_copy(self):
choice: Dict[str, str] = self.model.get_optimal_choice(A=self.assets["A-s"]*0.9, F=self.copying_fixed_costs["F(YN)c"]*0.9)
- self.assertEqual(choice["entrant"], self.model.ENTRANT_CHOICES["indifferent"])
- self.assertEqual(choice["incumbent"], self.model.INCUMBENT_CHOICES["copy"])
- self.assertEqual(choice["development"], self.model.DEVELOPMENT_OUTCOME["failure"])
+ self.assert_area_one(choice)
def test_path_kill_zone(self):
choice: Dict[str, str] = self.model.get_optimal_choice(A=self.assets["A-s"]*0.9, F=self.copying_fixed_costs["F(YN)c"]*1.1)
- self.assertEqual(choice["entrant"], self.model.ENTRANT_CHOICES["complement"])
- self.assertEqual(choice["incumbent"], self.model.INCUMBENT_CHOICES["refrain"])
- self.assertEqual(choice["development"], self.model.DEVELOPMENT_OUTCOME["success"])
+ self.assert_area_three(choice)
def test_path_substitute_refrain(self):
- choice: Dict[str, str] = self.model.get_optimal_choice(A=self.assets["A-s"]*1.1, F=self.copying_fixed_costs["F(YN)c"]*1.1)
- self.assertEqual(choice["entrant"], self.model.ENTRANT_CHOICES["substitute"])
- self.assertEqual(choice["incumbent"], self.model.INCUMBENT_CHOICES["refrain"])
- self.assertEqual(choice["development"], self.model.DEVELOPMENT_OUTCOME["success"])
+ choice: Dict[str, str] = self.model.get_optimal_choice(A=self.assets["A-s"]*1.1, F=self.copying_fixed_costs["F(YY)s"]*1.1)
+ self.assert_area_four(choice)
def test_path_substitute_copy(self):
- choice: Dict[str, str] = self.model.get_optimal_choice(A=self.assets["A-s"]*1.1, F=self.copying_fixed_costs["F(YN)c"]*0.9)
+ choice: Dict[str, str] = self.model.get_optimal_choice(A=self.assets["A-s"]*1.1, F=self.copying_fixed_costs["F(YY)s"]*0.9)
+ self.assert_area_two(choice)
+
+ def test_path_four_areas_corner(self):
+ choice: Dict[str, str] = self.model.get_optimal_choice(A=self.assets["A-s"], F=self.copying_fixed_costs["F(YY)s"])
+ self.assert_area_two(choice)
+
+ def test_path_area_three_area_four_corner(self):
+ choice: Dict[str, str] = self.model.get_optimal_choice(A=self.assets["A-s"], F=self.copying_fixed_costs["F(YN)s"])
+ self.assert_area_four(choice)
+
+ def test_path_area_three_area_four(self):
+ choice: Dict[str, str] = self.model.get_optimal_choice(A=self.assets["A-s"]*0.9, F=self.copying_fixed_costs["F(YN)s"])
+ self.assert_area_three(choice)
+
+ def test_path_area_one_area_two(self):
+ choice: Dict[str, str] = self.model.get_optimal_choice(A=self.assets["A-s"], F=min(self.copying_fixed_costs["F(YY)s"], self.copying_fixed_costs["F(YN)c"])*0.9)
+ self.assert_area_two(choice)
+
+ def test_path_area_one_area_three(self):
+ choice: Dict[str, str] = self.model.get_optimal_choice(A=self.assets["A-s"]*0.9, F=self.copying_fixed_costs["F(YN)c"])
+ self.assert_area_three(choice)
+
+ def test_path_area_two_area_four(self):
+ choice: Dict[str, str] = self.model.get_optimal_choice(A=self.assets["A-s"]*1.1, F=self.copying_fixed_costs["F(YY)s"])
+ self.assert_area_two(choice)
+
+
+class BargainingPowerModelTestBeta6(BaseModelTest):
+ @staticmethod
+ def setUpModel() -> IModel:
+ return BargainingPowerModel(beta=0.6)
+
+ def test_path_area_two_area_three(self):
+ choice: Dict[str, str] = self.model.get_optimal_choice(A=self.assets["A-s"], F=(self.copying_fixed_costs["F(YY)s"] + self.copying_fixed_costs["F(YN)c"])/2)
+ self.assert_area_two(choice)
+
+
+class BargainingPowerModelTestBeta4(BaseModelTest):
+ @staticmethod
+ def setUpModel() -> IModel:
+ return BargainingPowerModel(beta=0.4)
+
+ def test_path_area_one_area_four(self):
+ choice: Dict[str, str] = self.model.get_optimal_choice(A=self.assets["A-s"], F=(self.copying_fixed_costs["F(YY)s"] + self.copying_fixed_costs["F(YN)c"])/2)
+ self.assert_area_four(choice)
+
+
+class UnobservableModelTestBeta6(BargainingPowerModelTestBeta6):
+ @staticmethod
+ def setUpModel() -> IModel:
+ return UnobservableModel(beta=0.6)
+
+ def assert_area_three(self, choice: Dict[str, str]):
self.assertEqual(choice["entrant"], self.model.ENTRANT_CHOICES["substitute"])
self.assertEqual(choice["incumbent"], self.model.INCUMBENT_CHOICES["copy"])
- self.assertEqual(choice["development"], self.model.DEVELOPMENT_OUTCOME["success"])
+ self.assertEqual(choice["development"], self.model.DEVELOPMENT_OUTCOME["failure"])
+
+
+class UnobservableModelTestBeta4(BargainingPowerModelTestBeta4):
+ @staticmethod
+ def setUpModel() -> IModel:
+ return UnobservableModel(beta=0.4)
+
+ def assert_area_three(self, choice: Dict[str, str]):
+ self.assertEqual(choice["entrant"], self.model.ENTRANT_CHOICES["substitute"])
+ self.assertEqual(choice["incumbent"], self.model.INCUMBENT_CHOICES["copy"])
+ self.assertEqual(choice["development"], self.model.DEVELOPMENT_OUTCOME["failure"])
diff --git a/docs/Shelegia_Motta_2021.html b/docs/Shelegia_Motta_2021.html
index 1a89e2b..91f9f3a 100644
--- a/docs/Shelegia_Motta_2021.html
+++ b/docs/Shelegia_Motta_2021.html
@@ -61,7 +61,6 @@
This package implements the models of Shelegia and Motta (2021).
+This package implements the models of Shelegia and Motta (2021).
@@ -116,7 +115,7 @@
Or clone the repository via GitHub:
-git clone manuelbieri/shelegia_motta_2021
+git clone https://github.com/manuelbieri/shelegia_motta_2021.git
Introduction
@@ -218,40 +217,9 @@ Build Documentation
pdoc -o ./docs Shelegia_Motta_2021 --docformat "numpy" --math
-Dependencies
-
-
-
-
- Package
- Version
- Annotation
-
-
-
-
- matplotlib
- 3.4.3
- Always needed (includes numpy)
-
-
- jupyter
- 1.0.0
- Just for the demonstration in demo.ipynb
-
-
- pdoc
- 8.0.1
- Only to generate the documentation from scratch
-
-
-
-
-
-
Additional Notes
-For further information about the coordinates used in the code, see dev_notes.md.
+For further information about the coordinates used in the code, see resources/dev_notes.md.
@abc.abstractmethod - def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes: + def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None, **kwargs) -> matplotlib.axes.Axes: """ Plots the best answers of the incumbent to all possible actions of the entrant. @@ -959,6 +976,10 @@Returns
---------- axis : matplotlib.axes.Axes Axis to draw the plot on. (optional) + **kwargs + Optional key word arguments for the best answers plot.<br> + - title: title on top of the plot, instead of the default title.<br> + - options_legend: If true, an additional legend, explaining the options of the entrant and the incumbent, will be added to the plot.<br> Returns ------- @@ -977,6 +998,11 @@Parameters
@abc.abstractmethod - def plot_equilibrium(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes: + def plot_equilibrium(self, axis: matplotlib.axes.Axes = None, **kwargs) -> matplotlib.axes.Axes: """ Plots the equilibrium path based on the choices of the entrant and incumbent. @@ -1011,6 +1038,10 @@Returns
---------- axis : matplotlib.axes.Axes Axis to draw the plot on. (optional) + **kwargs + Optional key word arguments for the equilibrium plot.<br> + - title: title on top of the plot, instead of the default title.<br> + - options_legend: If true, an additional legend, explaining the options of the entrant and the incumbent, will be added to the plot.<br> Returns ------- @@ -1029,6 +1060,11 @@Parameters
from typing import Dict, List, Tuple, Literal +@@ -1031,7 +1054,7 @@from typing import Dict, List, Tuple, Literal, Final import matplotlib.axes import matplotlib.pyplot as plt @@ -158,7 +161,7 @@There are two players in our base model: The Incumbent, which sells the primary product, denoted by Ip, and a start-up, called the Entrant, which sells a product Ec complementary to Ip. (One may think of Ip as a platform, and Ec as a service or product which can be accessed through the platform.) We are interested in studying the choice of E between developing a substitute to Ip, denoted by Ep, or another complement to Ip, denoted by Ẽc and the choice of I between copying E’s original complementary product Ec by creating a perfect substitute Ic, or not. Since E may not have enough assets to cover the development cost of its second product, copying its current product will affect the entrant’s ability to obtain funding for the development. We shall show that the incumbent has a strategic incentive to copy when the entrant plans to compete, and to abstain from copying when it plans to create another complement. """ - tolerance: float = 10 ** (-8) + TOLERANCE: Final[float] = 10 ** (-8) """Tolerance for the comparison of two floating numbers.""" def __init__(self, u: float = 1, B: float = 0.5, small_delta: float = 0.5, delta: float = 0.51, @@ -378,7 +381,7 @@
Axis containing the plot. """ if axis is None: - fig, axis = plt.subplots() + figure, axis = plt.subplots() self._draw_thresholds(axis) for i, coordinates in enumerate(coordinates): @@ -386,18 +389,19 @@
axis.add_patch(poly) axis.legend(bbox_to_anchor=(1.3, 1), loc="upper left") + if kwargs.get('options_legend', False): + axis.text(-0.05, -0.4, self._create_options_legend(), verticalalignment='top') BaseModel._set_axis_labels(axis, title=kwargs.get('title', ''), x_label=kwargs.get('xlabel', 'Assets of the entrant'), y_label=kwargs.get('ylabel', 'Fixed costs of copying for the incumbent')) BaseModel._set_axis(axis) - plt.show() return axis - def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes: + def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None, **kwargs) -> matplotlib.axes.Axes: poly_coordinates: List[List[Tuple[float, float]]] = self._get_incumbent_best_answer_coordinates() poly_labels: List[str] = self._get_incumbent_best_answer_labels() - axis: matplotlib.axes.Axes = self._plot(title="Best Answers of the incumbent to the choices of the entrant", - coordinates=poly_coordinates, labels=poly_labels, axis=axis) + axis: matplotlib.axes.Axes = self._plot(title=kwargs.get("title", "Best Answers of the incumbent to the choices of the entrant"), + coordinates=poly_coordinates, labels=poly_labels, axis=axis, options_legend=kwargs.get('options_legend', False)) return axis def _create_choice_answer_label(self, entrant: Literal["complement", "substitute", "indifferent"], @@ -410,7 +414,7 @@
""" Returns a list containing the labels for the squares in the plot of the best answers of the incumbent to the choice of the entrant. - For the order of the labels refer to the file devnotes.md. + For the order of the labels refer to the file resources/dev_notes.md. Returns ------- @@ -441,7 +445,7 @@
""" Returns a list containing the coordinates for the squares in the plot of the best answers of the incumbent to the choice of the entrant. - For the order of the squares refer to the file devnotes.md. + For the order of the squares refer to the file resources/dev_notes.md. Returns ------- @@ -473,18 +477,18 @@
(x_max, y_max), (0, y_max), (0, self._copying_fixed_costs['F(YN)s']), (self._assets['A-s'], self._copying_fixed_costs['F(YN)s'])]] - def plot_equilibrium(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes: + def plot_equilibrium(self, axis: matplotlib.axes.Axes = None, **kwargs) -> matplotlib.axes.Axes: poly_coordinates: List[List[Tuple[float, float]]] = self._get_equilibrium_coordinates() poly_labels: List[str] = self._get_equilibrium_labels() - axis: matplotlib.axes.Axes = self._plot(title='Equilibrium Path in the base Model', - coordinates=poly_coordinates, labels=poly_labels, axis=axis) + axis: matplotlib.axes.Axes = self._plot(title=kwargs.get("title", "Equilibrium Path"), + coordinates=poly_coordinates, labels=poly_labels, axis=axis, options_legend=kwargs.get('options_legend', False)) return axis def _get_equilibrium_labels(self) -> List[str]: """ Returns a list containing the labels for the squares in the plot of the equilibrium path. - For the order of the squares refer to the file devnotes.md. + For the order of the squares refer to the file resources/dev_notes.md. Returns ------- @@ -505,7 +509,7 @@
""" Returns a list containing the coordinates for the squares in the plot of the equilibrium path. - For the order of the squares refer to the file devnotes.md. + For the order of the squares refer to the file resources/dev_notes.md. Returns ------- @@ -531,7 +535,7 @@
def plot_payoffs(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes: if axis is None: - fig, axis = plt.subplots() + figure, axis = plt.subplots() index = arange(0, len(self._payoffs) * 2, 2) bar_width = 0.35 opacity = 0.8 @@ -660,7 +664,7 @@
self._draw_horizontal_line_with_label(axis, y=self._copying_fixed_costs['F(YN)s'], label="$F^{YN}_S$") self._draw_horizontal_line_with_label(axis, y=self._copying_fixed_costs['F(YY)c'], label="$F^{YY}_C$") - if abs(self._copying_fixed_costs['F(YY)s'] - self._copying_fixed_costs['F(YN)c']) < BaseModel.tolerance: + if abs(self._copying_fixed_costs['F(YY)s'] - self._copying_fixed_costs['F(YN)c']) < BaseModel.TOLERANCE: self._draw_horizontal_line_with_label(axis, y=self._copying_fixed_costs['F(YY)s'], label="$F^{YY}_S=F^{YN}_C$") else: @@ -707,6 +711,19 @@
if label is not None: axis.text(x, label_y, label) + def _create_options_legend(self, latex: bool = True) -> str: + space: str = "$\quad$" if latex else "\t" + return "Options of the entrant:\n" + \ + space + self.ENTRANT_CHOICES['complement'] + ": Tries to develop an additional complementary product to a primary product.\n" + \ + space + self.ENTRANT_CHOICES['substitute'] + ": Tries to develop an substitute to the primary product of the incumbent.\n" + \ + space + self.ENTRANT_CHOICES['indifferent'] + " : Indifferent between the options mentioned above.\n" + \ + "Options of the incumbent:\n" + \ + space + self.INCUMBENT_CHOICES['copy'] + " : Tries to develop an additional complementary product to a primary product.\n" + \ + space + self.INCUMBENT_CHOICES['refrain'] + " : Tries to develop an additional complementary product to a primary product.\n" + \ + "Outcomes of the development:\n" + \ + space + self.DEVELOPMENT_OUTCOME['success'] + " : The additional product can be developed, since the entrant has sufficient assets.\n" + \ + space + self.DEVELOPMENT_OUTCOME['failure'] + " : The additional product can not be developed, since the entrant has not enough assets." + @staticmethod def _get_color(i: int) -> str: """ @@ -936,8 +953,8 @@
""" super(UnobservableModel, self).__init__(u=u, B=B, small_delta=small_delta, delta=delta, K=K, beta=beta) - def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes: - return self.plot_equilibrium(axis=axis) + def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None, **kwargs) -> matplotlib.axes.Axes: + return self.plot_equilibrium(axis=axis, kwargs=kwargs) def _create_choice_answer_label(self, entrant: Literal["complement", "substitute", "indifferent"], incumbent: Literal["copy", "refrain"], @@ -949,7 +966,7 @@
""" Returns a list containing the labels for the squares in the plot of the equilibrium path. - For the order of the squares refer to the file devnotes.md. + For the order of the squares refer to the file resources/dev_notes.md. Returns ------- @@ -966,6 +983,12 @@
self._create_choice_answer_label(entrant="substitute", incumbent="refrain", development="success") ] + def get_optimal_choice(self, A: float, F: float) -> Dict[str, str]: + result: Dict = super().get_optimal_choice(A, F) + if result["entrant"] == self.ENTRANT_CHOICES["complement"]: + result = {"entrant": self.ENTRANT_CHOICES["substitute"], "incumbent": self.INCUMBENT_CHOICES["copy"], "development": self.DEVELOPMENT_OUTCOME["failure"]} + return result + class AcquisitionModel(BargainingPowerModel): """ @@ -1007,9 +1030,9 @@
if __name__ == '__main__': - base_model = UnobservableModel(beta=0.6) - base_model.plot_equilibrium() - print(base_model) + bargaining_power_model = Shelegia_Motta_2021.BargainingPowerModel(beta=0.6) + bargaining_power_model.plot_equilibrium() + plt.show()
There are two players in our base model: The Incumbent, which sells the primary product, denoted by Ip, and a start-up, called the Entrant, which sells a product Ec complementary to Ip. (One may think of Ip as a platform, and Ec as a service or product which can be accessed through the platform.) We are interested in studying the choice of E between developing a substitute to Ip, denoted by Ep, or another complement to Ip, denoted by Ẽc and the choice of I between copying E’s original complementary product Ec by creating a perfect substitute Ic, or not. Since E may not have enough assets to cover the development cost of its second product, copying its current product will affect the entrant’s ability to obtain funding for the development. We shall show that the incumbent has a strategic incentive to copy when the entrant plans to compete, and to abstain from copying when it plans to create another complement. """ - tolerance: float = 10 ** (-8) + TOLERANCE: Final[float] = 10 ** (-8) """Tolerance for the comparison of two floating numbers.""" def __init__(self, u: float = 1, B: float = 0.5, small_delta: float = 0.5, delta: float = 0.51, @@ -1251,7 +1274,7 @@
Axis containing the plot. """ if axis is None: - fig, axis = plt.subplots() + figure, axis = plt.subplots() self._draw_thresholds(axis) for i, coordinates in enumerate(coordinates): @@ -1259,18 +1282,19 @@
axis.add_patch(poly) axis.legend(bbox_to_anchor=(1.3, 1), loc="upper left") + if kwargs.get('options_legend', False): + axis.text(-0.05, -0.4, self._create_options_legend(), verticalalignment='top') BaseModel._set_axis_labels(axis, title=kwargs.get('title', ''), x_label=kwargs.get('xlabel', 'Assets of the entrant'), y_label=kwargs.get('ylabel', 'Fixed costs of copying for the incumbent')) BaseModel._set_axis(axis) - plt.show() return axis - def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes: + def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None, **kwargs) -> matplotlib.axes.Axes: poly_coordinates: List[List[Tuple[float, float]]] = self._get_incumbent_best_answer_coordinates() poly_labels: List[str] = self._get_incumbent_best_answer_labels() - axis: matplotlib.axes.Axes = self._plot(title="Best Answers of the incumbent to the choices of the entrant", - coordinates=poly_coordinates, labels=poly_labels, axis=axis) + axis: matplotlib.axes.Axes = self._plot(title=kwargs.get("title", "Best Answers of the incumbent to the choices of the entrant"), + coordinates=poly_coordinates, labels=poly_labels, axis=axis, options_legend=kwargs.get('options_legend', False)) return axis def _create_choice_answer_label(self, entrant: Literal["complement", "substitute", "indifferent"], @@ -1283,7 +1307,7 @@
""" Returns a list containing the labels for the squares in the plot of the best answers of the incumbent to the choice of the entrant. - For the order of the labels refer to the file devnotes.md. + For the order of the labels refer to the file resources/dev_notes.md. Returns ------- @@ -1314,7 +1338,7 @@
""" Returns a list containing the coordinates for the squares in the plot of the best answers of the incumbent to the choice of the entrant. - For the order of the squares refer to the file devnotes.md. + For the order of the squares refer to the file resources/dev_notes.md. Returns ------- @@ -1346,18 +1370,18 @@
(x_max, y_max), (0, y_max), (0, self._copying_fixed_costs['F(YN)s']), (self._assets['A-s'], self._copying_fixed_costs['F(YN)s'])]] - def plot_equilibrium(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes: + def plot_equilibrium(self, axis: matplotlib.axes.Axes = None, **kwargs) -> matplotlib.axes.Axes: poly_coordinates: List[List[Tuple[float, float]]] = self._get_equilibrium_coordinates() poly_labels: List[str] = self._get_equilibrium_labels() - axis: matplotlib.axes.Axes = self._plot(title='Equilibrium Path in the base Model', - coordinates=poly_coordinates, labels=poly_labels, axis=axis) + axis: matplotlib.axes.Axes = self._plot(title=kwargs.get("title", "Equilibrium Path"), + coordinates=poly_coordinates, labels=poly_labels, axis=axis, options_legend=kwargs.get('options_legend', False)) return axis def _get_equilibrium_labels(self) -> List[str]: """ Returns a list containing the labels for the squares in the plot of the equilibrium path. - For the order of the squares refer to the file devnotes.md. + For the order of the squares refer to the file resources/dev_notes.md. Returns ------- @@ -1378,7 +1402,7 @@
""" Returns a list containing the coordinates for the squares in the plot of the equilibrium path. - For the order of the squares refer to the file devnotes.md. + For the order of the squares refer to the file resources/dev_notes.md. Returns ------- @@ -1404,7 +1428,7 @@
def plot_payoffs(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes: if axis is None: - fig, axis = plt.subplots() + figure, axis = plt.subplots() index = arange(0, len(self._payoffs) * 2, 2) bar_width = 0.35 opacity = 0.8 @@ -1533,7 +1557,7 @@
self._draw_horizontal_line_with_label(axis, y=self._copying_fixed_costs['F(YN)s'], label="$F^{YN}_S$") self._draw_horizontal_line_with_label(axis, y=self._copying_fixed_costs['F(YY)c'], label="$F^{YY}_C$") - if abs(self._copying_fixed_costs['F(YY)s'] - self._copying_fixed_costs['F(YN)c']) < BaseModel.tolerance: + if abs(self._copying_fixed_costs['F(YY)s'] - self._copying_fixed_costs['F(YN)c']) < BaseModel.TOLERANCE: self._draw_horizontal_line_with_label(axis, y=self._copying_fixed_costs['F(YY)s'], label="$F^{YY}_S=F^{YN}_C$") else: @@ -1580,6 +1604,19 @@
if label is not None: axis.text(x, label_y, label) + def _create_options_legend(self, latex: bool = True) -> str: + space: str = "$\quad$" if latex else "\t" + return "Options of the entrant:\n" + \ + space + self.ENTRANT_CHOICES['complement'] + ": Tries to develop an additional complementary product to a primary product.\n" + \ + space + self.ENTRANT_CHOICES['substitute'] + ": Tries to develop an substitute to the primary product of the incumbent.\n" + \ + space + self.ENTRANT_CHOICES['indifferent'] + " : Indifferent between the options mentioned above.\n" + \ + "Options of the incumbent:\n" + \ + space + self.INCUMBENT_CHOICES['copy'] + " : Tries to develop an additional complementary product to a primary product.\n" + \ + space + self.INCUMBENT_CHOICES['refrain'] + " : Tries to develop an additional complementary product to a primary product.\n" + \ + "Outcomes of the development:\n" + \ + space + self.DEVELOPMENT_OUTCOME['success'] + " : The additional product can be developed, since the entrant has sufficient assets.\n" + \ + space + self.DEVELOPMENT_OUTCOME['failure'] + " : The additional product can not be developed, since the entrant has not enough assets." + @staticmethod def _get_color(i: int) -> str: """ @@ -1740,10 +1777,10 @@
Parameters
Tolerance for the comparison of two floating numbers.
@@ -2092,17 +2129,18 @@def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes: +@@ -2115,6 +2153,11 @@def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None, **kwargs) -> matplotlib.axes.Axes: poly_coordinates: List[List[Tuple[float, float]]] = self._get_incumbent_best_answer_coordinates() poly_labels: List[str] = self._get_incumbent_best_answer_labels() - axis: matplotlib.axes.Axes = self._plot(title="Best Answers of the incumbent to the choices of the entrant", - coordinates=poly_coordinates, labels=poly_labels, axis=axis) + axis: matplotlib.axes.Axes = self._plot(title=kwargs.get("title", "Best Answers of the incumbent to the choices of the entrant"), + coordinates=poly_coordinates, labels=poly_labels, axis=axis, options_legend=kwargs.get('options_legend', False)) return axisParameters
def plot_equilibrium(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes: +@@ -2156,6 +2200,11 @@def plot_equilibrium(self, axis: matplotlib.axes.Axes = None, **kwargs) -> matplotlib.axes.Axes: poly_coordinates: List[List[Tuple[float, float]]] = self._get_equilibrium_coordinates() poly_labels: List[str] = self._get_equilibrium_labels() - axis: matplotlib.axes.Axes = self._plot(title='Equilibrium Path in the base Model', - coordinates=poly_coordinates, labels=poly_labels, axis=axis) + axis: matplotlib.axes.Axes = self._plot(title=kwargs.get("title", "Equilibrium Path"), + coordinates=poly_coordinates, labels=poly_labels, axis=axis, options_legend=kwargs.get('options_legend', False)) return axisParameters
def plot_payoffs(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes: if axis is None: - fig, axis = plt.subplots() + figure, axis = plt.subplots() index = arange(0, len(self._payoffs) * 2, 2) bar_width = 0.35 opacity = 0.8 @@ -2734,7 +2783,7 @@Returns
Inherited Members
def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None) -> matplotlib.axes.Axes: - return self.plot_equilibrium(axis=axis) +@@ -2866,6 +2922,11 @@def plot_incumbent_best_answers(self, axis: matplotlib.axes.Axes = None, **kwargs) -> matplotlib.axes.Axes: + return self.plot_equilibrium(axis=axis, kwargs=kwargs)Parameters
def get_optimal_choice(self, A: float, F: float) -> Dict[str, str]: + result: Dict = super().get_optimal_choice(A, F) + if result["entrant"] == self.ENTRANT_CHOICES["complement"]: + result = {"entrant": self.ENTRANT_CHOICES["substitute"], "incumbent": self.INCUMBENT_CHOICES["copy"], "development": self.DEVELOPMENT_OUTCOME["failure"]} + return result +
Returns the optimal choice of the entrant and the incumbent based on a pair of assets of the entrant and fixed costs for copying of the incumbent.
+ +The output dictionary will contain the following details:
+ +\n\n\n\n\n\n\n\n\n
\n\nInstallation over PyPI:
\n\npip install Shelegia-Motta-2021\n
\n\nOr clone the repository via GitHub:
\n\ngit clone manuelbieri/shelegia_motta_2021\n
\n\nSince all models implement the Shelegia_Motta_2021.IModel.IModel - Interface, therefore all models provide the same functionality (public methods), even though the results may change substantially.
\n\nFor all models add the following import statement:
\n\nimport Shelegia_Motta_2021.Models\n
\n\nbase_model = Shelegia_Motta_2021.Models.BaseModel()\n
\n\nbargaining_power_model = Shelegia_Motta_2021.Models.BargainingPowerModel()\n
\n\nunobservable_model = Shelegia_Motta_2021.Models.UnobservableModel()\n
\n\nacquisition_model = Shelegia_Motta_2021.Models.AcquisitionModel()\n
\n\n# every model type can be plugged in without changing the following code.\nmodel: Shelegia_Motta_2021.IModel.IModel = Shelegia_Motta_2021.Models.BaseModel()\n\n# print string representation of the model\nprint(model)\n\n# plot the best answers of the incumbent to the choice of the entrant\nmodel.plot_incumbent_best_answers()\n\n# plot the equilibrium path\nmodel.plot_equilibrium()\n
\n\nPackage | \nVersion | \nAnnotation | \n
---|---|---|
matplotlib | \n3.4.3 | \nAlways needed (includes numpy) | \n
jupyter | \n1.0.0 | \nJust for the demonstration in demo.ipynb | \n
pdoc | \n8.0.1 | \nOnly to generate the documentation from scratch | \n
\nThese packages include all the needed imports for the functionality of this package.
For the latest version of the documentation open manuelbieri.github.io/shelegia_motta_2021 in your browser or call:
\n\nimport Shelegia_Motta_2021\n\nShelegia_Motta_2021.docs()\n
\n\nInstall the pdoc package:
\n\npip install pdoc\n
\n\nGenerate api-documentation with the following command:
\n\npdoc -o ./docs Shelegia_Motta_2021 --docformat \"numpy\" --math\n
\n\nFor further information about the coordinates used in the code, see dev_notes.md.
\n"}, {"fullname": "Shelegia_Motta_2021.docs", "modulename": "Shelegia_Motta_2021", "qualname": "docs", "type": "function", "doc": "Opens the latest published version of the documentation of this package.
\n", "parameters": [], "funcdef": "def"}, {"fullname": "Shelegia_Motta_2021.IModel", "modulename": "Shelegia_Motta_2021.IModel", "qualname": "", "type": "module", "doc": "\n"}, {"fullname": "Shelegia_Motta_2021.IModel.IModel", "modulename": "Shelegia_Motta_2021.IModel", "qualname": "IModel", "type": "class", "doc": "Interface for all models in Shelegia and Motta (2021).
\n"}, {"fullname": "Shelegia_Motta_2021.IModel.IModel.__init__", "modulename": "Shelegia_Motta_2021.IModel", "qualname": "IModel.__init__", "type": "function", "doc": "\n", "parameters": ["self"], "funcdef": "def"}, {"fullname": "Shelegia_Motta_2021.IModel.IModel.ENTRANT_CHOICES", "modulename": "Shelegia_Motta_2021.IModel", "qualname": "IModel.ENTRANT_CHOICES", "type": "variable", "doc": "Contains all the possible product choices of the entrant.
\n\nContains all the possible answers of the incumbent to the choice of the entrant.
\n\nContains all the possible outcomes of the development for the chosen product of the entrant or the merged entity.
\n\nReturns the asset thresholds of the entrant.
\n\nNumber and type of the thresholds will be specific to the model.
\n\nReturns the fixed costs for copying thresholds of the incumbent.
\n\nNumber and type of the thresholds will be specific to the model.
\n\nReturns the payoffs for different market configurations.
\n\nA market configuration can include:
\n\nMarket Config. | \n$\\pi(I)$ | \n$\\pi(E)$ | \nCS | \nW | \n
---|---|---|---|---|
$I_P$ ; $E_C$ | \nN.A. | \nN.A. | \nN.A. | \nN.A. | \n
$I_P + I_C$ ; $E_C$ | \nN.A. | \nN.A. | \nN.A. | \nN.A. | \n
$I_P$ ; $E_P + E_C$ | \nN.A. | \nN.A. | \nN.A. | \nN.A. | \n
$I_P + I_C$ ; $E_P + E_C$ | \nN.A. | \nN.A. | \nN.A. | \nN.A. | \n
$I_P$ ; $E_C + \\tilde{E}_C$ | \nN.A. | \nN.A. | \nN.A. | \nN.A. | \n
$I_P + I_C$ ; $E_C + \\tilde{E}_C$ | \nN.A. | \nN.A. | \nN.A. | \nN.A. | \n
\nThe payoffs are specific to the models.
Returns the optimal choice of the entrant and the incumbent based on a pair of assets of the entrant and fixed costs for copying of the incumbent.
\n\nThe output dictionary will contain the following details:
\n\nPlots the best answers of the incumbent to all possible actions of the entrant.
\n\nPlots the equilibrium path based on the choices of the entrant and incumbent.
\n\nPlots the payoffs for different market configurations.
\n\nThere are two players in our base model: The Incumbent, which sells the primary product, denoted by Ip, and a start-up, called the Entrant, which sells a product Ec complementary to Ip. (One may think of Ip as a platform, and Ec as a service or product which can be accessed through the platform.) We are interested in studying the choice of E between developing a substitute to Ip, denoted by Ep, or another complement to Ip, denoted by \u1ebcc and the choice of I between copying E\u2019s original complementary product Ec by creating a perfect substitute Ic, or not. Since E may not have enough assets to cover the development cost of its second product, copying its current product will affect the entrant\u2019s ability to obtain funding for the development. We shall show that the incumbent has a strategic incentive to copy when the entrant plans to compete, and to abstain from copying when it plans to create another complement.
\n"}, {"fullname": "Shelegia_Motta_2021.Models.BaseModel.__init__", "modulename": "Shelegia_Motta_2021.Models", "qualname": "BaseModel.__init__", "type": "function", "doc": "Initializes a valid BaseModel object.
\n\nThe following preconditions have to be satisfied:
\n\nTolerance for the comparison of two floating numbers.
\n"}, {"fullname": "Shelegia_Motta_2021.Models.BaseModel.get_asset_values", "modulename": "Shelegia_Motta_2021.Models", "qualname": "BaseModel.get_asset_values", "type": "function", "doc": "Returns the asset thresholds of the entrant.
\n\nThreshold $\\:\\:\\:\\:\\:$ | \nName $\\:\\:\\:\\:\\:$ | \nFormula $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n
---|---|---|
$A_S$ | \nA_s | \n$(2)\\: B + K - \\Delta - 3\\delta/2$ | \n
$A_C$ | \nA_c | \n$(3)\\: B + K - 3\\delta/2$ | \n
$\\overline{A}_S$ | \nA-s | \n$(4)\\: B + K - \\Delta$ | \n
$\\overline{A}_C$ | \nA-c | \n$(5)\\: B + K - \\delta/2$ | \n
Returns the fixed costs for copying thresholds of the incumbent.
\n\nThreshold $\\:\\:\\:\\:\\:$ | \nName $\\:\\:\\:\\:\\:$ | \nFormula $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n
---|---|---|
$F^{YY}_S$ | \nF(YY)s | \n$(6)\\: \\delta/2$ | \n
$F^{YN}_S$ | \nF(YN)s | \n$(6)\\: u + 3\\delta/2$ | \n
$F^{YY}_C$ | \nF(YY)c | \n$(6)\\: \\delta$ | \n
$F^{YN}_C$ | \nF(YN)c | \n$(6)\\: \\delta/2$ | \n
Returns the payoffs for different market configurations.
\n\nA market configuration can include:
\n\nMarket Config. $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n$\\pi(I) \\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n$\\pi(E) \\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \nCS $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \nW $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n
---|---|---|---|---|
$I_P$ ; $E_C$ | \n$u + \\delta/2$ | \n$\\delta/2$ | \n0 | \n$u + \\delta$ | \n
$I_P + I_C$ ; $E_C$ | \n$u + \\delta$ | \n0 | \n0 | \n$u + \\delta$ | \n
$I_P$ ; $E_P + E_C$ | \n0 | \n$\\Delta + \\delta$ | \n$u$ | \n$u + \\Delta + \\delta$ | \n
$I_P + I_C$ ; $E_P + E_C$ | \n0 | \n$\\Delta$ | \n$u + \\delta$ | \n$u + \\Delta + \\delta$ | \n
$I_P$ ; $E_C + \\tilde{E}_C$ | \n$u + \\delta$ | \n$\\delta$ | \n0 | \n$u + 2\\delta$ | \n
$I_P + I_C$ ; $E_C + \\tilde{E}_C$ | \n$u + 3\\delta/2$ | \n$\\delta/2$ | \n0 | \n$u + 2\\delta$ | \n
Returns the optimal choice of the entrant and the incumbent based on a pair of assets of the entrant and fixed costs for copying of the incumbent.
\n\nThe output dictionary will contain the following details:
\n\nPlots the best answers of the incumbent to all possible actions of the entrant.
\n\nPlots the equilibrium path based on the choices of the entrant and incumbent.
\n\nPlots the payoffs for different market configurations.
\n\nBesides the parameters used in the paper, this class will introduce the parameter $\\beta$ in the models, called\nthe bargaining power of the incumbent. In the paper the default value 0.5 is used to derive the results.
\n"}, {"fullname": "Shelegia_Motta_2021.Models.BargainingPowerModel.__init__", "modulename": "Shelegia_Motta_2021.Models", "qualname": "BargainingPowerModel.__init__", "type": "function", "doc": "Besides $\\beta$ the parameters in this model do not change compared to Shelegia_Motta_2021.Models.BaseModel.
\n\nReturns the asset thresholds of the entrant.
\n\nThreshold $\\:\\:\\:\\:\\:$ | \nName $\\:\\:\\:\\:\\:$ | \nFormula $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n
---|---|---|
$A_S$ | \nA_s | \n$B + K - \\Delta - \\delta(2 - \\beta)$ | \n
$A_C$ | \nA_c | \n$B + K - 3\\delta(1 - \\beta)$ | \n
$\\overline{A}_S$ | \nA-s | \n$B + K - \\Delta$ | \n
$\\overline{A}_C$ | \nA-c | \n$B + K - \\delta(1 - \\beta)$ | \n
Returns the fixed costs for copying thresholds of the incumbent.
\n\nThreshold $\\:\\:\\:\\:\\:$ | \nName $\\:\\:\\:\\:\\:$ | \nFormula $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n
---|---|---|
$F^{YY}_S$ | \nF(YY)s | \n$\\delta(1 - \\beta)$ | \n
$F^{YN}_S$ | \nF(YN)s | \n$u + \\delta(2 - \\beta)$ | \n
$F^{YY}_C$ | \nF(YY)c | \n$2\\delta(1 - \\beta)$ | \n
$F^{YN}_C$ | \nF(YN)c | \n$\\delta(2 - \\beta)$ | \n
Returns the payoffs for different market configurations.
\n\nA market configuration can include:
\n\nMarket Config. $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n$\\pi(I) \\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n$\\pi(E) \\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \nCS $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \nW $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n
---|---|---|---|---|
$I_P$ ; $E_C$ | \n$u + \\delta\\beta$ | \n$\\delta(1 - \\beta)$ | \n0 | \n$u + \\delta$ | \n
$I_P + I_C$ ; $E_C$ | \n$u + \\delta$ | \n0 | \n0 | \n$u + \\delta$ | \n
$I_P$ ; $E_P + E_C$ | \n0 | \n$\\Delta + \\delta$ | \n$u$ | \n$u + \\Delta + \\delta$ | \n
$I_P + I_C$ ; $E_P + E_C$ | \n0 | \n$\\Delta$ | \n$u + \\delta$ | \n$u + \\Delta + \\delta$ | \n
$I_P$ ; $E_C + \\tilde{E}_C$ | \n$u + 2\\delta\\beta$ | \n$2\\delta(1 - \\beta)$ | \n0 | \n$u + 2\\delta$ | \n
$I_P + I_C$ ; $E_C + \\tilde{E}_C$ | \n$u + \\delta(1 + \\beta)$ | \n$\\delta(1 - \\beta)$ | \n0 | \n$u + 2\\delta$ | \n
This model indicates that if the incumbent were not able to observe the entrant at the moment of choosing, the \u201ckill zone\u201d effect whereby the entrant stays away from the substitute in order to avoid being copied) would not take place. Intuitively, in the game as we studied it so far, the only reason why the entrant is choosing a trajectory leading to another complement is that it anticipates that if it chose one leading to a substitute, the incumbent would copy, making it an inefficient strategy for entering the market. However, if the incumbent cannot observe the entrant\u2019s choice of strategy, the entrant could not hope to strategically affect the decision of the incumbent. This would lead to the entrant having a host of new opportunities when entering the market and it makes competing with a large company much more attractive.
\n"}, {"fullname": "Shelegia_Motta_2021.Models.UnobservableModel.__init__", "modulename": "Shelegia_Motta_2021.Models", "qualname": "UnobservableModel.__init__", "type": "function", "doc": "The parameters do not change compared to Shelegia_Motta_2021.Models.BargainingPowerModel.
\n", "parameters": ["self", "u", "B", "small_delta", "delta", "K", "beta"], "funcdef": "def"}, {"fullname": "Shelegia_Motta_2021.Models.UnobservableModel.plot_incumbent_best_answers", "modulename": "Shelegia_Motta_2021.Models", "qualname": "UnobservableModel.plot_incumbent_best_answers", "type": "function", "doc": "Plots the best answers of the incumbent to all possible actions of the entrant.
\n\nIn order to explore how acquisitions may modify the entrant\u2019s and the incumbent\u2019s strategic choices, we extend the base model in order to allow an acquisition to take place after the incumbent commits to copying the entrant\u2019s original complementary product (between t=1 and t=2, see table 2). We assume that the incumbent and the entrant share the gains (if any) attained from the acquisition equally.
\n"}, {"fullname": "Shelegia_Motta_2021.Models.AcquisitionModel.__init__", "modulename": "Shelegia_Motta_2021.Models", "qualname": "AcquisitionModel.__init__", "type": "function", "doc": "An additional constraint is added compared to Shelegia_Motta_2021.Models.BaseModel. Namely, $\\Delta$ has to be bigger than $\\delta$, meaning the innovation of the entrant is not too drastic.
\n\nMeanwhile, the parameters do not change compared to Shelegia_Motta_2021.Models.BargainingPowerModel.
\n", "parameters": ["self", "u", "B", "small_delta", "delta", "K"], "funcdef": "def"}, {"fullname": "Shelegia_Motta_2021.Models.AcquisitionModel.get_copying_fixed_costs_values", "modulename": "Shelegia_Motta_2021.Models", "qualname": "AcquisitionModel.get_copying_fixed_costs_values", "type": "function", "doc": "Returns the fixed costs for copying thresholds of the incumbent.
\n\nAdditional thresholds for the fixed cost of copying of the incumbent compared to the Shelegia_Motta_2021.Models.BargainingModel:
\n\nThreshold $\\:\\:\\:\\:\\:$ | \nName $\\:\\:\\:\\:\\:$ | \nFormula $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n
---|---|---|
$F^{ACQ}_S$ | \nF(ACQ)s | \n$\\frac{(u + \\Delta - K)}{2} + \\delta(2 - \\beta)$ | \n
$F^{ACQ}_C$ | \nF(ACQ)c | \n$\\frac{K}{2} + \\delta(2.5 - 3\\beta)$ | \n
This package implements the models of Shelegia and Motta (2021).
\n\n\n\n\n\n\n\n\n\n\n
\n\nInstallation over PyPI:
\n\npip install Shelegia-Motta-2021\n
\n\nOr clone the repository via GitHub:
\n\ngit clone https://github.com/manuelbieri/shelegia_motta_2021.git\n
\n\nSince all models implement the Shelegia_Motta_2021.IModel.IModel - Interface, therefore all models provide the same functionality (public methods), even though the results may change substantially.
\n\nFor all models add the following import statement:
\n\nimport Shelegia_Motta_2021.Models\n
\n\nbase_model = Shelegia_Motta_2021.Models.BaseModel()\n
\n\nbargaining_power_model = Shelegia_Motta_2021.Models.BargainingPowerModel()\n
\n\nunobservable_model = Shelegia_Motta_2021.Models.UnobservableModel()\n
\n\nacquisition_model = Shelegia_Motta_2021.Models.AcquisitionModel()\n
\n\n# every model type can be plugged in without changing the following code.\nmodel: Shelegia_Motta_2021.IModel.IModel = Shelegia_Motta_2021.Models.BaseModel()\n\n# print string representation of the model\nprint(model)\n\n# plot the best answers of the incumbent to the choice of the entrant\nmodel.plot_incumbent_best_answers()\n\n# plot the equilibrium path\nmodel.plot_equilibrium()\n
\n\nPackage | \nVersion | \nAnnotation | \n
---|---|---|
matplotlib | \n3.4.3 | \nAlways needed (includes numpy) | \n
jupyter | \n1.0.0 | \nJust for the demonstration in demo.ipynb | \n
pdoc | \n8.0.1 | \nOnly to generate the documentation from scratch | \n
\nThese packages include all the needed imports for the functionality of this package.
For the latest version of the documentation open manuelbieri.github.io/shelegia_motta_2021 in your browser or call:
\n\nimport Shelegia_Motta_2021\n\nShelegia_Motta_2021.docs()\n
\n\nInstall the pdoc package:
\n\npip install pdoc\n
\n\nGenerate api-documentation with the following command:
\n\npdoc -o ./docs Shelegia_Motta_2021 --docformat \"numpy\" --math\n
\n\nFor further information about the coordinates used in the code, see resources/dev_notes.md.
\n"}, {"fullname": "Shelegia_Motta_2021.docs", "modulename": "Shelegia_Motta_2021", "qualname": "docs", "type": "function", "doc": "Opens the latest published version of the documentation of this package.
\n", "parameters": [], "funcdef": "def"}, {"fullname": "Shelegia_Motta_2021.IModel", "modulename": "Shelegia_Motta_2021.IModel", "qualname": "", "type": "module", "doc": "\n"}, {"fullname": "Shelegia_Motta_2021.IModel.IModel", "modulename": "Shelegia_Motta_2021.IModel", "qualname": "IModel", "type": "class", "doc": "Interface for all models in Shelegia and Motta (2021).
\n"}, {"fullname": "Shelegia_Motta_2021.IModel.IModel.__init__", "modulename": "Shelegia_Motta_2021.IModel", "qualname": "IModel.__init__", "type": "function", "doc": "\n", "parameters": ["self"], "funcdef": "def"}, {"fullname": "Shelegia_Motta_2021.IModel.IModel.ENTRANT_CHOICES", "modulename": "Shelegia_Motta_2021.IModel", "qualname": "IModel.ENTRANT_CHOICES", "type": "variable", "doc": "Contains all the possible product choices of the entrant.
\n\nContains all the possible answers of the incumbent to the choice of the entrant.
\n\nContains all the possible outcomes of the development for the chosen product of the entrant or the merged entity.
\n\nReturns the asset thresholds of the entrant.
\n\nNumber and type of the thresholds will be specific to the model.
\n\nReturns the fixed costs for copying thresholds of the incumbent.
\n\nNumber and type of the thresholds will be specific to the model.
\n\nReturns the payoffs for different market configurations.
\n\nA market configuration can include:
\n\nMarket Config. | \n$\\pi(I)$ | \n$\\pi(E)$ | \nCS | \nW | \n
---|---|---|---|---|
$I_P$ ; $E_C$ | \nN.A. | \nN.A. | \nN.A. | \nN.A. | \n
$I_P + I_C$ ; $E_C$ | \nN.A. | \nN.A. | \nN.A. | \nN.A. | \n
$I_P$ ; $E_P + E_C$ | \nN.A. | \nN.A. | \nN.A. | \nN.A. | \n
$I_P + I_C$ ; $E_P + E_C$ | \nN.A. | \nN.A. | \nN.A. | \nN.A. | \n
$I_P$ ; $E_C + \\tilde{E}_C$ | \nN.A. | \nN.A. | \nN.A. | \nN.A. | \n
$I_P + I_C$ ; $E_C + \\tilde{E}_C$ | \nN.A. | \nN.A. | \nN.A. | \nN.A. | \n
\nThe payoffs are specific to the models.
Returns the optimal choice of the entrant and the incumbent based on a pair of assets of the entrant and fixed costs for copying of the incumbent.
\n\nThe output dictionary will contain the following details:
\n\nPlots the best answers of the incumbent to all possible actions of the entrant.
\n\nPlots the equilibrium path based on the choices of the entrant and incumbent.
\n\nPlots the payoffs for different market configurations.
\n\nThere are two players in our base model: The Incumbent, which sells the primary product, denoted by Ip, and a start-up, called the Entrant, which sells a product Ec complementary to Ip. (One may think of Ip as a platform, and Ec as a service or product which can be accessed through the platform.) We are interested in studying the choice of E between developing a substitute to Ip, denoted by Ep, or another complement to Ip, denoted by \u1ebcc and the choice of I between copying E\u2019s original complementary product Ec by creating a perfect substitute Ic, or not. Since E may not have enough assets to cover the development cost of its second product, copying its current product will affect the entrant\u2019s ability to obtain funding for the development. We shall show that the incumbent has a strategic incentive to copy when the entrant plans to compete, and to abstain from copying when it plans to create another complement.
\n"}, {"fullname": "Shelegia_Motta_2021.Models.BaseModel.__init__", "modulename": "Shelegia_Motta_2021.Models", "qualname": "BaseModel.__init__", "type": "function", "doc": "Initializes a valid BaseModel object.
\n\nThe following preconditions have to be satisfied:
\n\nTolerance for the comparison of two floating numbers.
\n"}, {"fullname": "Shelegia_Motta_2021.Models.BaseModel.get_asset_values", "modulename": "Shelegia_Motta_2021.Models", "qualname": "BaseModel.get_asset_values", "type": "function", "doc": "Returns the asset thresholds of the entrant.
\n\nThreshold $\\:\\:\\:\\:\\:$ | \nName $\\:\\:\\:\\:\\:$ | \nFormula $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n
---|---|---|
$A_S$ | \nA_s | \n$(2)\\: B + K - \\Delta - 3\\delta/2$ | \n
$A_C$ | \nA_c | \n$(3)\\: B + K - 3\\delta/2$ | \n
$\\overline{A}_S$ | \nA-s | \n$(4)\\: B + K - \\Delta$ | \n
$\\overline{A}_C$ | \nA-c | \n$(5)\\: B + K - \\delta/2$ | \n
Returns the fixed costs for copying thresholds of the incumbent.
\n\nThreshold $\\:\\:\\:\\:\\:$ | \nName $\\:\\:\\:\\:\\:$ | \nFormula $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n
---|---|---|
$F^{YY}_S$ | \nF(YY)s | \n$(6)\\: \\delta/2$ | \n
$F^{YN}_S$ | \nF(YN)s | \n$(6)\\: u + 3\\delta/2$ | \n
$F^{YY}_C$ | \nF(YY)c | \n$(6)\\: \\delta$ | \n
$F^{YN}_C$ | \nF(YN)c | \n$(6)\\: \\delta/2$ | \n
Returns the payoffs for different market configurations.
\n\nA market configuration can include:
\n\nMarket Config. $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n$\\pi(I) \\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n$\\pi(E) \\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \nCS $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \nW $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n
---|---|---|---|---|
$I_P$ ; $E_C$ | \n$u + \\delta/2$ | \n$\\delta/2$ | \n0 | \n$u + \\delta$ | \n
$I_P + I_C$ ; $E_C$ | \n$u + \\delta$ | \n0 | \n0 | \n$u + \\delta$ | \n
$I_P$ ; $E_P + E_C$ | \n0 | \n$\\Delta + \\delta$ | \n$u$ | \n$u + \\Delta + \\delta$ | \n
$I_P + I_C$ ; $E_P + E_C$ | \n0 | \n$\\Delta$ | \n$u + \\delta$ | \n$u + \\Delta + \\delta$ | \n
$I_P$ ; $E_C + \\tilde{E}_C$ | \n$u + \\delta$ | \n$\\delta$ | \n0 | \n$u + 2\\delta$ | \n
$I_P + I_C$ ; $E_C + \\tilde{E}_C$ | \n$u + 3\\delta/2$ | \n$\\delta/2$ | \n0 | \n$u + 2\\delta$ | \n
Returns the optimal choice of the entrant and the incumbent based on a pair of assets of the entrant and fixed costs for copying of the incumbent.
\n\nThe output dictionary will contain the following details:
\n\nPlots the best answers of the incumbent to all possible actions of the entrant.
\n\nPlots the equilibrium path based on the choices of the entrant and incumbent.
\n\nPlots the payoffs for different market configurations.
\n\nBesides the parameters used in the paper, this class will introduce the parameter $\\beta$ in the models, called\nthe bargaining power of the incumbent. In the paper the default value 0.5 is used to derive the results.
\n"}, {"fullname": "Shelegia_Motta_2021.Models.BargainingPowerModel.__init__", "modulename": "Shelegia_Motta_2021.Models", "qualname": "BargainingPowerModel.__init__", "type": "function", "doc": "Besides $\\beta$ the parameters in this model do not change compared to Shelegia_Motta_2021.Models.BaseModel.
\n\nReturns the asset thresholds of the entrant.
\n\nThreshold $\\:\\:\\:\\:\\:$ | \nName $\\:\\:\\:\\:\\:$ | \nFormula $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n
---|---|---|
$A_S$ | \nA_s | \n$B + K - \\Delta - \\delta(2 - \\beta)$ | \n
$A_C$ | \nA_c | \n$B + K - 3\\delta(1 - \\beta)$ | \n
$\\overline{A}_S$ | \nA-s | \n$B + K - \\Delta$ | \n
$\\overline{A}_C$ | \nA-c | \n$B + K - \\delta(1 - \\beta)$ | \n
Returns the fixed costs for copying thresholds of the incumbent.
\n\nThreshold $\\:\\:\\:\\:\\:$ | \nName $\\:\\:\\:\\:\\:$ | \nFormula $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n
---|---|---|
$F^{YY}_S$ | \nF(YY)s | \n$\\delta(1 - \\beta)$ | \n
$F^{YN}_S$ | \nF(YN)s | \n$u + \\delta(2 - \\beta)$ | \n
$F^{YY}_C$ | \nF(YY)c | \n$2\\delta(1 - \\beta)$ | \n
$F^{YN}_C$ | \nF(YN)c | \n$\\delta(2 - \\beta)$ | \n
Returns the payoffs for different market configurations.
\n\nA market configuration can include:
\n\nMarket Config. $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n$\\pi(I) \\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n$\\pi(E) \\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \nCS $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \nW $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n
---|---|---|---|---|
$I_P$ ; $E_C$ | \n$u + \\delta\\beta$ | \n$\\delta(1 - \\beta)$ | \n0 | \n$u + \\delta$ | \n
$I_P + I_C$ ; $E_C$ | \n$u + \\delta$ | \n0 | \n0 | \n$u + \\delta$ | \n
$I_P$ ; $E_P + E_C$ | \n0 | \n$\\Delta + \\delta$ | \n$u$ | \n$u + \\Delta + \\delta$ | \n
$I_P + I_C$ ; $E_P + E_C$ | \n0 | \n$\\Delta$ | \n$u + \\delta$ | \n$u + \\Delta + \\delta$ | \n
$I_P$ ; $E_C + \\tilde{E}_C$ | \n$u + 2\\delta\\beta$ | \n$2\\delta(1 - \\beta)$ | \n0 | \n$u + 2\\delta$ | \n
$I_P + I_C$ ; $E_C + \\tilde{E}_C$ | \n$u + \\delta(1 + \\beta)$ | \n$\\delta(1 - \\beta)$ | \n0 | \n$u + 2\\delta$ | \n
This model indicates that if the incumbent were not able to observe the entrant at the moment of choosing, the \u201ckill zone\u201d effect whereby the entrant stays away from the substitute in order to avoid being copied) would not take place. Intuitively, in the game as we studied it so far, the only reason why the entrant is choosing a trajectory leading to another complement is that it anticipates that if it chose one leading to a substitute, the incumbent would copy, making it an inefficient strategy for entering the market. However, if the incumbent cannot observe the entrant\u2019s choice of strategy, the entrant could not hope to strategically affect the decision of the incumbent. This would lead to the entrant having a host of new opportunities when entering the market and it makes competing with a large company much more attractive.
\n"}, {"fullname": "Shelegia_Motta_2021.Models.UnobservableModel.__init__", "modulename": "Shelegia_Motta_2021.Models", "qualname": "UnobservableModel.__init__", "type": "function", "doc": "The parameters do not change compared to Shelegia_Motta_2021.Models.BargainingPowerModel.
\n", "parameters": ["self", "u", "B", "small_delta", "delta", "K", "beta"], "funcdef": "def"}, {"fullname": "Shelegia_Motta_2021.Models.UnobservableModel.plot_incumbent_best_answers", "modulename": "Shelegia_Motta_2021.Models", "qualname": "UnobservableModel.plot_incumbent_best_answers", "type": "function", "doc": "Plots the best answers of the incumbent to all possible actions of the entrant.
\n\nReturns the optimal choice of the entrant and the incumbent based on a pair of assets of the entrant and fixed costs for copying of the incumbent.
\n\nThe output dictionary will contain the following details:
\n\nIn order to explore how acquisitions may modify the entrant\u2019s and the incumbent\u2019s strategic choices, we extend the base model in order to allow an acquisition to take place after the incumbent commits to copying the entrant\u2019s original complementary product (between t=1 and t=2, see table 2). We assume that the incumbent and the entrant share the gains (if any) attained from the acquisition equally.
\n"}, {"fullname": "Shelegia_Motta_2021.Models.AcquisitionModel.__init__", "modulename": "Shelegia_Motta_2021.Models", "qualname": "AcquisitionModel.__init__", "type": "function", "doc": "An additional constraint is added compared to Shelegia_Motta_2021.Models.BaseModel. Namely, $\\Delta$ has to be bigger than $\\delta$, meaning the innovation of the entrant is not too drastic.
\n\nMeanwhile, the parameters do not change compared to Shelegia_Motta_2021.Models.BargainingPowerModel.
\n", "parameters": ["self", "u", "B", "small_delta", "delta", "K"], "funcdef": "def"}, {"fullname": "Shelegia_Motta_2021.Models.AcquisitionModel.get_copying_fixed_costs_values", "modulename": "Shelegia_Motta_2021.Models", "qualname": "AcquisitionModel.get_copying_fixed_costs_values", "type": "function", "doc": "Returns the fixed costs for copying thresholds of the incumbent.
\n\nAdditional thresholds for the fixed cost of copying of the incumbent compared to the Shelegia_Motta_2021.Models.BargainingModel:
\n\nThreshold $\\:\\:\\:\\:\\:$ | \nName $\\:\\:\\:\\:\\:$ | \nFormula $\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:\\:$ | \n
---|---|---|
$F^{ACQ}_S$ | \nF(ACQ)s | \n$\\frac{(u + \\Delta - K)}{2} + \\delta(2 - \\beta)$ | \n
$F^{ACQ}_C$ | \nF(ACQ)c | \n$\\frac{K}{2} + \\delta(2.5 - 3\\beta)$ | \n