Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

Example Model

Austin Drenski edited this page Feb 6, 2017 · 34 revisions

This example looks at the effect of a 5 % price shock on one supplier in a sector where four suppliers initially have equal market shares.

                 -------------------
                 |     Retail      |
                 -------------------
                /       / \         \
              /        /   \          \
            /         /     \           \
          /          /       \            \
-----------   -----------   -----------   -----------  
|Supplier1|   |Supplier2|   |Supplier3|   |Supplier4|
-----------   -----------   -----------   ----------- 

Inputs

Parameter Value
Elasticity of substitution 4.00
Elasticity of supply 5.00
Elasticity of demand -1.00
Initial price 1.00
Market share 0.25
Shock (only Supplier3) 0.05

Results

Supplier ProducerPrice ConsumerPrice ConsumerPriceIndex
Retail 1.0099
Supplier1 1.0032 1.0032
Supplier2 1.0032 1.0032
Supplier3 0.9817 1.0308
Supplier4 1.0032 1.0032

Code

using System;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using AD.IO;
using AD.PartialEquilibriumApi.Optimization;

namespace AD.PartialEquilibriumApi.Example
{
    public static class Example
    {
        public static void Example1()
        {
            XmlFilePath structureFile = CreateTempXmlFile();
            DelimitedFilePath dataFile = CreateTempCsvFile();

            // Read in the model and the data.
            XElement model = CreateModelFromFile(structureFile, dataFile);
            //XElement model = CreateModelFromInteractive(dataFile);

            // Set the consumer prices.
            model.SetConsumerPrices(model.DescendantsAndSelf()
                                        .Select(x => x.InitialPrice())
                                        .ToArray());

            // Apply the price shocks.
            model.ShockAllProducerPrices();

            // Calculate the price indices.
            model.CalculateConsumerPriceIndex();

            // Calculate the market equilibrium starting on the root.
            model.CalculateRootMarketEquilibrium();

            // Create boolean vector indicating which nodes (in document-order) are variable.
            bool[] variables =
                new bool[]
                {
                    false,
                    true,
                    true,
                    true,
                    true
                };

            // Create the objective function.
            Func<double[], double> objectiveFunction =
                x =>
                {
                    // Update consumer prices to the argument vector.
                    // Result: x[i] if variables[i] is true
                    model.SetConsumerPrices(x, variables);
                    // Shock the current prices:
                    // Result: currentPrice * (1 + shock)
                    model.ShockAllProducerPrices();
                    // Calculate a price index for the sector:
                    // Result: [Σ marketShare[i] * (price[i] ^ (1 - elasticityOfSubstitution[i])] ^ [1 / (1 - elasticityOfSubstitution)]
                    model.CalculateConsumerPriceIndex();
                    // Caclulate the market equilibrium. Zero means equilibrium.
                    // [shockedPrice ^ elasticityOfSupply] - [(priceIndex ^ (elasticityOfSubstitution + elasticityOfDemand)) / (initialPrice ^ elasticityOfSubstitution)]
                    model.CalculateRootMarketEquilibrium();
                    // Return the sector's equilibrium value to the caller.
                    return model.MarketEquilibrium();
                };

            // Set up the simplex solver.
            Simplex simplex =
                new Simplex(
                    objectiveFunction: x => objectiveFunction(x),
                    lowerBound: 0,
                    upperBound: 100,
                    dimensions: 5,
                    numberOfSolutions: 5,
                    iterations: 1000,
                    textWriter: Console.Out);

            // Find the minimum solution.
            Solution solution = simplex.Minimize();

            // Update the XML tree one more time with the optimal result.
            double[] result = solution.Vector;
            model.SetConsumerPrices(result, variables);
            model.ShockAllProducerPrices();
            model.CalculateConsumerPriceIndex();
            model.CalculateRootMarketEquilibrium();

            // Calculate new market shares
            model.CalculateAllFinalMarketShares();

            // Print the results.
            Console.WriteLine("-----------------------------------------------------------------------------------------");
            XmlWriterSettings settings = new XmlWriterSettings
            {
                Encoding = Encoding.UTF8,
                Indent = true,
                NewLineOnAttributes = true,
                IndentChars = "    "
            };
            using (XmlWriter writer = XmlWriter.Create(Console.Out, settings))
            {
                model.WriteTo(writer);
            }
            Console.WriteLine();
            Console.WriteLine("-----------------------------------------------------------------------------------------");
            Console.ReadLine();
        }

        private static XElement CreateModelFromFile(XmlFilePath structureFile, DelimitedFilePath dataFile)
        {
            return XElement.Load(structureFile)
                           .DefineAttributeData(dataFile);
        }

        private static XmlFilePath CreateTempXmlFile()
        {
            string xml = Path.ChangeExtension(Path.GetTempFileName(), ".xml");
            using (StreamWriter writer = new StreamWriter(xml))
            {
                writer.WriteLine(
                    @"<Retail>
                        <Supplier1 />
                        <Supplier2 />
                        <Supplier3 />
                        <Supplier4 />
                      </Retail>");
            }
            return new XmlFilePath(xml);
        }

        private static DelimitedFilePath CreateTempCsvFile()
        {
            string csv = Path.ChangeExtension(Path.GetTempFileName(), ".csv");
            using (StreamWriter writer = new StreamWriter(csv))
            {
                writer.WriteLine("ElasticityOfSubstitution,ElasticityOfSupply,ElasticityOfDemand,InitialPrice,InitialMarketShare,Shock");
                writer.WriteLine("4,5,-1,1.0,1.00,0.00");
                writer.WriteLine("4,5,-1,1.0,0.25,0.00");
                writer.WriteLine("4,5,-1,1.0,0.25,0.00");
                writer.WriteLine("4,5,-1,1.0,0.25,0.05");
                writer.WriteLine("4,5,-1,1.0,0.25,0.00");
            }
            return new DelimitedFilePath(csv, ',');
        }
}

Console output

> i =    0: [ 2.9191e01, 4.6731e01, 6.3266e01, 4.6951e01, 9.8215e01 ] = 7.3285e17
> i =   10: [ 2.0871e01, 6.3110e00, 2.8254e01, 2.4324e01, 3.6187e01 ] = 2.8723e14
> i =   20: [ 1.5218e01, 2.5642e01, 1.6444e01, 1.3909e01, 1.2137e01 ] = 1.2472e14
> i =   30: [ 1.5218e01, 1.9188e01, 1.7190e01, 8.0037e00, 1.5040e01 ] = 8.8153e12
> i =   40: [ 1.5218e01, 1.9188e01, 1.7190e01, 8.0037e00, 1.5040e01 ] = 8.8153e12
> i =   50: [ 1.6471e01, 1.8020e01, 1.6955e01, 9.8264e00, 1.4551e01 ] = 6.2931e12
> i =   60: [ 1.6799e01, 1.7953e01, 1.4754e01, 7.9602e00, 1.5202e01 ] = 5.5694e12
> i =   70: [ 1.5452e01, 1.6067e01, 1.2161e01, 3.2924e00, 1.7982e01 ] = 1.9658e12
> i =   80: [ 1.2798e01, 1.4553e01, 8.3466e00, 1.3129e01, 2.2162e01 ] = 6.9731e11
> i =   90: [ 1.3456e01, 1.3415e01, 7.9699e00, 1.2167e01, 2.2189e01 ] = 4.5513e11
> i =  100: [ 1.2455e01, 1.2848e01, 7.7077e00, 1.1784e01, 2.3291e01 ] = 2.6452e11
> i =  110: [ 5.7413e00, 8.8984e00, 5.2747e00, 5.6521e00, 3.1002e01 ] = 3.1950e09
> i =  120: [ 8.5978e-01, 2.7922e00, 1.8091e00, 2.6156e-01, 3.8426e01 ] = 2.9256e04
> i =  130: [ 8.5978e-01, 2.7922e00, 1.8091e00, 2.6156e-01, 3.8426e01 ] = 2.9256e04
> i =  140: [ 8.5978e-01, 2.7922e00, 1.8091e00, 2.6156e-01, 3.8426e01 ] = 2.9256e04
> i =  150: [ 1.3789e00, 5.5558e-01, 3.3286e-01, 1.7819e-01, 3.9862e01 ] = 3.8392e02
> i =  160: [ 1.3789e00, 5.5558e-01, 3.3286e-01, 1.7819e-01, 3.9862e01 ] = 3.8392e02
> i =  170: [ 1.3789e00, 5.5558e-01, 3.3286e-01, 1.7819e-01, 3.9862e01 ] = 3.8392e02
> i =  180: [ 1.3789e00, 5.5558e-01, 3.3286e-01, 1.7819e-01, 3.9862e01 ] = 3.8392e02
> i =  190: [ 1.3789e00, 5.5558e-01, 3.3286e-01, 1.7819e-01, 3.9862e01 ] = 3.8392e02
> i =  200: [ 1.3789e00, 5.5558e-01, 3.3286e-01, 1.7819e-01, 3.9862e01 ] = 3.8392e02
> i =  210: [ 1.2956e00, 7.5734e-01, 1.0807e00, 6.4949e-01, 3.9285e01 ] = 2.3582e01
> i =  220: [ 1.2956e00, 7.5734e-01, 1.0807e00, 6.4949e-01, 3.9285e01 ] = 2.3582e01
> i =  230: [ 1.2956e00, 7.5734e-01, 1.0807e00, 6.4949e-01, 3.9285e01 ] = 2.3582e01
> i =  240: [ 1.2956e00, 7.5734e-01, 1.0807e00, 6.4949e-01, 3.9285e01 ] = 2.3582e01
> i =  250: [ 1.2956e00, 7.5734e-01, 1.0807e00, 6.4949e-01, 3.9285e01 ] = 2.3582e01
> i =  260: [ 1.2956e00, 7.5734e-01, 1.0807e00, 6.4949e-01, 3.9285e01 ] = 2.3582e01
> i =  270: [ 8.7920e-01, 6.8873e-01, 1.1177e00, 6.1521e-01, 3.9410e01 ] = 1.2206e01
> i =  280: [ 9.5244e-01, 7.9167e-01, 1.1684e00, 6.8653e-01, 3.9258e01 ] = 9.3677e00
> i =  290: [ 1.0415e00, 8.7920e-01, 1.2136e00, 7.7859e-01, 3.9040e01 ] = 7.3464e00
> i =  300: [ 1.0099e00, 9.6487e-01, 1.2290e00, 8.1786e-01, 3.8940e01 ] = 6.0237e00
> i =  310: [ 1.0864e00, 1.0352e00, 1.2190e00, 8.9289e-01, 3.8711e01 ] = 4.5238e00
> i =  320: [ 9.8136e-01, 1.0473e00, 1.1705e00, 9.0105e-01, 3.8631e01 ] = 2.5033e00
> i =  330: [ 1.0202e00, 1.0300e00, 1.1691e00, 1.0379e00, 3.8228e01 ] = 1.2066e00
> i =  340: [ 9.6520e-01, 1.0621e00, 1.1201e00, 1.0195e00, 3.8227e01 ] = 8.8776e-01
> i =  350: [ 1.0001e00, 1.0611e00, 1.1290e00, 1.0319e00, 3.8202e01 ] = 7.5197e-01
> i =  360: [ 1.0166e00, 1.0725e00, 1.1158e00, 1.0207e00, 3.8221e01 ] = 6.4910e-01
> i =  370: [ 1.0223e00, 1.0679e00, 1.1167e00, 1.0306e00, 3.8193e01 ] = 6.0864e-01
> i =  380: [ 1.0499e00, 1.0665e00, 1.0988e00, 1.0370e00, 3.8156e01 ] = 5.0399e-01
> i =  390: [ 1.0163e00, 1.0654e00, 1.0486e00, 1.0037e00, 3.8198e01 ] = 2.8355e-01
> i =  400: [ 1.0193e00, 1.0580e00, 1.0396e00, 1.0169e00, 3.8150e01 ] = 2.0866e-01
> i =  410: [ 1.0002e00, 1.0511e00, 1.0339e00, 1.0049e00, 3.8178e01 ] = 1.7239e-01
> i =  420: [ 9.9290e-01, 1.0444e00, 1.0261e00, 1.0057e00, 3.8167e01 ] = 1.4603e-01
> i =  430: [ 9.8898e-01, 1.0311e00, 1.0293e00, 1.0172e00, 3.8136e01 ] = 9.1712e-02
> i =  440: [ 9.9755e-01, 1.0161e00, 1.0387e00, 1.0281e00, 3.8115e01 ] = 5.5867e-02
> i =  450: [ 1.0048e00, 1.0164e00, 1.0442e00, 1.0290e00, 3.8118e01 ] = 5.1599e-02
> i =  460: [ 1.0051e00, 1.0195e00, 1.0380e00, 1.0273e00, 3.8117e01 ] = 4.7991e-02
> i =  470: [ 1.0063e00, 1.0132e00, 1.0367e00, 1.0258e00, 3.8119e01 ] = 3.5348e-02
> i =  480: [ 1.0130e00, 1.0054e00, 1.0403e00, 1.0150e00, 3.8156e01 ] = 1.3933e-02
> i =  490: [ 1.0122e00, 1.0062e00, 1.0396e00, 1.0129e00, 3.8161e01 ] = 1.0295e-02
> i =  500: [ 1.0107e00, 1.0028e00, 1.0319e00, 1.0061e00, 3.8173e01 ] = 3.9700e-03
> i =  510: [ 1.0092e00, 1.0052e00, 1.0334e00, 1.0063e00, 3.8173e01 ] = 2.4077e-03
> i =  520: [ 1.0029e00, 1.0049e00, 1.0300e00, 1.0036e00, 3.8177e01 ] = 2.7907e-04
> i =  530: [ 1.0038e00, 1.0036e00, 1.0318e00, 1.0031e00, 3.8181e01 ] = 6.4543e-05
> i =  540: [ 1.0036e00, 1.0034e00, 1.0311e00, 1.0032e00, 3.8180e01 ] = 1.1306e-05
> i =  550: [ 1.0032e00, 1.0033e00, 1.0308e00, 1.0032e00, 3.8179e01 ] = 1.5583e-06
> i =  560: [ 1.0034e00, 1.0033e00, 1.0308e00, 1.0033e00, 3.8179e01 ] = 7.6830e-07
> i =  570: [ 1.0033e00, 1.0032e00, 1.0308e00, 1.0033e00, 3.8179e01 ] = 1.5024e-07
> i =  580: [ 1.0033e00, 1.0033e00, 1.0308e00, 1.0033e00, 3.8179e01 ] = 5.4235e-08
> i =  590: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 1.9210e-08
> i =  600: [ 1.0033e00, 1.0033e00, 1.0308e00, 1.0033e00, 3.8179e01 ] = 8.5378e-09
> i =  610: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 4.0556e-09
> i =  620: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 2.1087e-10
> i =  630: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 3.6298e-11
> i =  640: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 7.5108e-12
> i =  650: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 7.5338e-13
> i =  660: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 1.7234e-13
> i =  670: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 7.3639e-14
> i =  680: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 2.7048e-14
> i =  690: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 3.5010e-15
> i =  700: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 9.2075e-16
> i =  710: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 4.0725e-16
> i =  720: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 2.5618e-16
> i =  730: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 9.8858e-17
> i =  740: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 2.8622e-17
> i =  750: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 1.4852e-17
> i =  760: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 4.0164e-18
> i =  770: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 2.8271e-19
> i =  780: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 2.9178e-20
> i =  790: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 4.6985e-21
> i =  800: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 5.7695e-22
> i =  810: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 1.2424e-22
> i =  820: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 2.9649e-23
> i =  830: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 4.0499e-24
> i =  840: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 9.0473e-25
> i =  850: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 1.8120e-25
> i =  860: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 2.9279e-27
> i =  870: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 2.9279e-27
> i =  880: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 1.1672e-27
> i =  890: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 1.7523e-28
> i =  900: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 4.2007e-29
> i =  910: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 1.7749e-30
> i =  920: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 1.7749e-30
> i =  930: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 1.7749e-30
> i =  940: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 1.7749e-30
> i =  950: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 1.7749e-30
> i =  960: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 1.7749e-30
> i =  970: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 1.7749e-30
> i =  980: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 1.7749e-30
> i =  990: [ 1.0033e00, 1.0033e00, 1.0309e00, 1.0033e00, 3.8179e01 ] = 1.7749e-30
-----------------------------------------------------------------------------------------
<?xml version="1.0" encoding="IBM437"?>
<Retail
    ElasticityOfSubstitution="4"
    ElasticityOfSupply="5"
    ElasticityOfDemand="-1"
    InitialPrice="1"
    ConsumerPrice="1"
    InitialMarketShare="1"
    Shock="0"
    ProducerPrice="1"
    ConsumerPriceIndex="1.0099076384845791"
    MarketEquilibrium="1.7749370367472766E-30"
    FinalMarketShare="1">
    <Supplier1
        ElasticityOfSubstitution="4"
        ElasticityOfSupply="5"
        ElasticityOfDemand="-1"
        InitialPrice="1"
        ConsumerPrice="1.0032916989904535"
        InitialMarketShare="0.25"
        Shock="0"
        ProducerPrice="1.0032916989904535"
        ConsumerPriceIndex="0.247547389952549"
        MarketEquilibrium="6.6613381477509392E-16"
        FinalMarketShare="0.25497835956737486" />
    <Supplier2
        ElasticityOfSubstitution="4"
        ElasticityOfSupply="5"
        ElasticityOfDemand="-1"
        InitialPrice="1"
        ConsumerPrice="1.0032916989904535"
        InitialMarketShare="0.25"
        Shock="0"
        ProducerPrice="1.0032916989904535"
        ConsumerPriceIndex="0.247547389952549"
        MarketEquilibrium="6.6613381477509392E-16"
        FinalMarketShare="0.25497835956737486" />
    <Supplier3
        ElasticityOfSubstitution="4"
        ElasticityOfSupply="5"
        ElasticityOfDemand="-1"
        InitialPrice="1"
        ConsumerPrice="1.0308584894302912"
        InitialMarketShare="0.25"
        Shock="0.05"
        ProducerPrice="0.98176998993361064"
        ConsumerPriceIndex="0.22821429957986097"
        MarketEquilibrium="-6.6613381477509392E-16"
        FinalMarketShare="0.2350649212978754" />
    <Supplier4
        ElasticityOfSubstitution="4"
        ElasticityOfSupply="5"
        ElasticityOfDemand="-1"
        InitialPrice="1"
        ConsumerPrice="1.0032916989904535"
        InitialMarketShare="0.25"
        Shock="0"
        ProducerPrice="1.0032916989904535"
        ConsumerPriceIndex="0.247547389952549"
        MarketEquilibrium="6.6613381477509392E-16"
        FinalMarketShare="0.25497835956737486" />
</Retail>
-----------------------------------------------------------------------------------------
Clone this wiki locally