public void CalculateEquilibriumLP(List <MarketPoint> demandCurve, List <MarketPoint> supplyCurve) { var equilQ = MarketClearing.FindEquilibrium(supplyCurve.ToRectangularArray(), demandCurve.ToRectangularArray()); _equilibrium = new MarketPoint() { Price = (decimal)equilQ.eqPrice, Volume = (decimal)equilQ.eqQuantity }; }
public void CalculateEquilibrium() { /* Find bounding box */ var maxMinVolume = Math.Max(DemandCurve.Min(d => d.Volume), SupplyCurve.Min(d => d.Volume)); var minMaxVolume = Math.Min(DemandCurve.Max(d => d.Volume), SupplyCurve.Max(d => d.Volume)); var maxMinPrice = Math.Max(DemandCurve.Min(d => d.Price), SupplyCurve.Min(d => d.Price)); var minMaxPrice = Math.Min(DemandCurve.Max(d => d.Price), SupplyCurve.Max(d => d.Price)); var subDemandCurve = DemandCurve .Where(d => maxMinVolume <= d.Volume && d.Volume <= minMaxVolume) .Where(d => maxMinPrice <= d.Price && d.Price <= minMaxPrice) .ToList(); var subSupplyCurve = SupplyCurve .Where(d => maxMinVolume <= d.Volume && d.Volume <= minMaxVolume) .Where(d => maxMinPrice <= d.Price && d.Price <= minMaxPrice) .ToList(); try { /* Run equilibrium procedure */ if (_eqlibriumAlgorithm == EquilibriumAlgorithm.CurveIntersection) { //naive inefficient method CalculateEquilibriumBruteForce(subDemandCurve, subSupplyCurve); } else if (_eqlibriumAlgorithm == EquilibriumAlgorithm.WelfareMaximization) { //the main approached used in the literature CalculateEquilibriumLP(subDemandCurve, subSupplyCurve); } } catch (Exception ex) { //log it.. //should instead be null, so that it could go missing... //adopt a simple interpolation technique... _equilibrium = new MarketPoint() { Price = 0, Volume = 0 }; } }
//TODO: refactor to a more efficient algorithm! TOO SLOW... WAY TOO SLOW... public void CalculateEquilibriumBruteForce(List <MarketPoint> demandCurve, List <MarketPoint> supplyCurve) { /* Brute force calculation for now */ var distances = new List <Tuple <int, int, double> >(); for (int i = 0; i < demandCurve.Count; i++) { var dPoint = demandCurve[i]; for (int j = 0; j < supplyCurve.Count; j++) { var sPoint = supplyCurve[j]; var l = Line.FindLength(dPoint.Volume, dPoint.Price, sPoint.Volume, sPoint.Price); var t = new Tuple <int, int, double>(i, j, l); distances.Add(t); } } var smallestDistance = distances .OrderBy(d => d.Item3) .First(); var secondSmallestDistance = distances .Where(d => d.Item3 > smallestDistance.Item3) .OrderBy(d => d.Item3) .First(); var iStart = smallestDistance.Item1; var iEnd = secondSmallestDistance.Item1; //should not happen //DemandStart is closer to supply since Demand is downward sloping... so it's ordered decreasingly... if (iStart == iEnd && iStart > 1) { iEnd = iStart - 1; } var jStart = smallestDistance.Item2; var jEnd = secondSmallestDistance.Item2; //should not happen, if (jStart == jEnd && jStart < SupplyCurve.Count - 1) { jEnd = jStart + 1; } /* Interpolate to find equilibrium values */ var demandLine = new Line( demandCurve[iStart].Volume, demandCurve[iStart].Price, demandCurve[iEnd].Volume, demandCurve[iEnd].Price); var supplyLine = new Line( supplyCurve[jStart].Volume, supplyCurve[jStart].Price, supplyCurve[jEnd].Volume, supplyCurve[jEnd].Price); Point <decimal> intersection = demandLine.Intersect(supplyLine); _equilibrium = new MarketPoint() { Price = intersection.Y, Volume = intersection.X }; }
public void CalculateEquilibrium() { /* Find bounding box */ var maxMinVolume = Math.Max(DemandCurve.Min(d => d.Volume), SupplyCurve.Min(d => d.Volume)); var minMaxVolume = Math.Min(DemandCurve.Max(d => d.Volume), SupplyCurve.Max(d => d.Volume)); var maxMinPrice = Math.Max(DemandCurve.Min(d => d.Price), SupplyCurve.Min(d => d.Price)); var minMaxPrice = Math.Min(DemandCurve.Max(d => d.Price), SupplyCurve.Max(d => d.Price)); var subDemandCurve = DemandCurve .Where(d => maxMinVolume <= d.Volume && d.Volume <= minMaxVolume) .Where(d => maxMinPrice <= d.Price && d.Price <= minMaxPrice) .ToList(); var subSupplyCurve = SupplyCurve .Where(d => maxMinVolume <= d.Volume && d.Volume <= minMaxVolume) .Where(d => maxMinPrice <= d.Price && d.Price <= minMaxPrice) .ToList(); try { /* Run equilibrium procedure */ if (_eqlibriumAlgorithm == EquilibriumAlgorithm.CurveIntersection) //naive inefficient method CalculateEquilibriumBruteForce(subDemandCurve, subSupplyCurve); else if (_eqlibriumAlgorithm == EquilibriumAlgorithm.WelfareMaximization) //the main approached used in the literature CalculateEquilibriumLP(subDemandCurve, subSupplyCurve); } catch(Exception ex) { //log it.. //should instead be null, so that it could go missing... //adopt a simple interpolation technique... _equilibrium = new MarketPoint() { Price = 0, Volume = 0 }; } }
//TODO: refactor to a more efficient algorithm! TOO SLOW... WAY TOO SLOW... public void CalculateEquilibriumBruteForce(List<MarketPoint> demandCurve, List<MarketPoint> supplyCurve) { /* Brute force calculation for now */ var distances = new List<Tuple<int,int,double>>(); for (int i = 0; i < demandCurve.Count; i++) { var dPoint = demandCurve[i]; for (int j = 0; j < supplyCurve.Count; j++) { var sPoint = supplyCurve[j]; var l = Line.FindLength(dPoint.Volume, dPoint.Price, sPoint.Volume, sPoint.Price); var t = new Tuple<int, int, double>(i, j, l); distances.Add(t); } } var smallestDistance = distances .OrderBy(d=>d.Item3) .First(); var secondSmallestDistance = distances .Where(d=>d.Item3 > smallestDistance.Item3) .OrderBy(d => d.Item3) .First(); var iStart = smallestDistance.Item1; var iEnd = secondSmallestDistance.Item1; //should not happen //DemandStart is closer to supply since Demand is downward sloping... so it's ordered decreasingly... if (iStart == iEnd && iStart > 1) iEnd = iStart - 1; var jStart = smallestDistance.Item2; var jEnd = secondSmallestDistance.Item2; //should not happen, if (jStart == jEnd && jStart < SupplyCurve.Count - 1) jEnd = jStart + 1; /* Interpolate to find equilibrium values */ var demandLine = new Line( demandCurve[iStart].Volume, demandCurve[iStart].Price, demandCurve[iEnd].Volume, demandCurve[iEnd].Price); var supplyLine = new Line( supplyCurve[jStart].Volume, supplyCurve[jStart].Price, supplyCurve[jEnd].Volume, supplyCurve[jEnd].Price); Point<decimal> intersection = demandLine.Intersect(supplyLine); _equilibrium = new MarketPoint() { Price = intersection.Y, Volume = intersection.X }; }
public void CalculateEquilibriumLP(List<MarketPoint> demandCurve, List<MarketPoint> supplyCurve) { var equilQ = MarketClearing.FindEquilibrium(supplyCurve.ToRectangularArray(), demandCurve.ToRectangularArray()); _equilibrium = new MarketPoint() { Price = (decimal)equilQ.eqPrice, Volume = (decimal)equilQ.eqQuantity }; }