Introduction
Optimization models that rely on single point forecasts assume the future is known with certainty. In reality, demand is almost never known with certainty. True demand may be higher or lower than forecasted, and the best decisions can be quite sensitive to those variations. When an optimization model uses only a point forecast, it doesn’t account for the uncertainty and risk that decision-makers know is always present.Instead of generating a single point estimate, PyMC generates a full predictive distribution of plausible future values. This provides a richer representation of the uncertain future.
Once that uncertainty is quantified, FICO Xpress incorporates the full predictive distribution into a broader optimization model to make better, more robust decisions under uncertainty.
This getting-started blog demonstrates two ways that FICO Xpress can incorporate a predictive distribution into an optimization model. The first uses a chance-constrained model. The second uses a Conditional Value at Risk (CVaR) model. The chance-constrained model controls how often planned production fails to meet demand, while the CVaR model controls how severe those shortfalls are in the most extreme scenarios.
Together, these two approaches provide a strong foundation for decision-making under uncertainty and are more robust than optimizing with point forecasts alone. While these are not the only approaches, both are widely used in industry.
What is PyMC?
PyMC is an open-source probabilistic programming language in Python. It provides users a simple building-block-like API for mathematical modeling with probability distributions. The nice thing about probabilistic programming languages is that they provide a natural way to model uncertainty about parameters, data, or predictions. A probabilistic model can be used as a generative simulation - to explore the possible scenarios consistent with a set of assumptions - or as an inference engine - to update uncertain beliefs in light of incoming evidence. The primary inference tool is a state-of-the-art implementation of Hamiltonian Monte Carlo, an MCMC algorithm that lets you efficiently sample from high-dimensional probability distributions. PyMC is powered by a lovely backend known as Pytensor, an engine that will automatically rewrite your model into a more numerically efficient or stable form while compiling it to a variety of backends - JAX (for CPUs and GPUs), Numba, C.What is FICO Xpress?
FICO® Xpress provides a commercial suite of mathematical optimization solvers and tools to build, solve, and deploy decision models in production workflows. It includes commercial solvers for LP, MIP, (MI)QP, (MI)QCP, (MI)SOCP, CP, NLP, and global (MI)NLP problem types with APIs into Python, C, C++, Java, .NET, R, MATLAB®, Julia, Pyomo, and JuMP. Due to this flexibility, customers can easily incorporate FICO Xpress into the programming language of their choice to solve their most complex decision problems reliably at scale.In addition to its APIs and commercial solvers, FICO Xpress has numerous other products for enabling seamless production deployment.
Companies in every industry rely on FICO Xpress to quickly deliver solutions to their most complex, enterprise-scale decision problems. Several of those customers include PepsiCo, FedEx, DoorDash, Shell, AFRY,American Airlines, Artelys, Procter & Gamble, and Southwest Airlines.
A Simple Application: Power Generation with Uncertain Demand
Ontario's electricity grid draws on multiple power sources with different costs, capacities, and emissions profiles. The input data in this example are hypothetical and are used solely to illustrate the chance-constrained and CVaR modeling frameworks.The columns are further defined below.
The goal of this example is to determine how much electricity to generate for each power source each day so that daily demand is met as reliably and cost-effectively as possible across a 181-day planning horizon.
A clean energy requirement imposes a rule that at least 80% of total electricity generation each day must come from clean sources.
The system operator must make generation-planning decisions months in advance, balancing cost and reliability to ensure clean energy targets are met. To provide sufficient electricity to the public, a planner needs to anticipate future electricity demand. The chart below shows historical daily electricity demand in Ontario.
When forecasting daily electricity demand, planners need more than a simple forecast. They need a forecast distribution with quantifiable uncertainty, and a decision framework that translates uncertainty into a set of decisions.
PyMC generates the forecast distribution, and FICO Xpress incorporates that distribution to make decisions under uncertainty.
Forecasting Electricity Demand Using PyMC
Consider a simple model of electrical demand. We should expect there to be high demand in the winter and summer months as people turn up the heating or air conditioning. To capture that, we can include a periodic function that completes two periods each year and has a parameter to estimate the amplitude to the seasonal changes. We’d also expect there to be a long-term trend in energy demand. Ontario has a growing population and has been experiencing more extreme weather in the last several years. There might also be some short-term weekly variation. Friday nights might consume more power than Monday nights. Demand on the weekends might decrease as schools and offices close. We can include a periodic function with a weekly period. These represent our main model components.A central decision in building a Bayesian model is selecting a likelihood function. This represents the pattern of unexplained variation: perhaps there is a heatwave that suddenly requires more demand. Our model won’t anticipate any particular heatwave. But it can be built to be robust to surprises. In our case, we selected a LogNormal distribution for its asymmetrical skew and heavy tails toward large numbers. It has some nice properties compared to the more conventional normal distribution. Unexpected events tend to put more pressure on the grid rather than less. Moreover, the kind of strain that extreme weather puts on the grid tends to be non-linear – if the temperature jumps from 35C to 40C in the summer that is a very different story then when the temperature jumps from 20C to 25C. The choice of likelihood also makes a difference when it comes to demand planning: we should try to ensure that our plans are informed by the possibility of extreme events.
PyMC models are built in a context wrapper that bundles data, model structure and prior distributions together into a single object. Below, we are describing prior distributions for the two types of periodic effects.
You can perform all the standard arithmetic operations on distributions. Below we show how to take the dot product of a prior distribution with a data array and add both types of periodic effects into a single time-series.
fourier_component=fourier_betas_yearly@ data_yearly.T +fourier_betas_weekly @ data_weekly.T
The intercept and long-term trends are defined similarly, and all effects are added together to get a single prediction.
There have been some implicit scaling choices made throughout: the LogNormal is naturally defined in terms of the log space. So that’s why the prior effects are so small - the intercept has a prior around 13, but that gives you a prior prediction centered around half a million megawatt hours and an interval roughly between a quarter million and two million.
The payoff is that we get a reconstruction of our training data with a full representation of uncertainty. In the backend, PyMC uses a Monte Carlo Markov Chain algorithm to generate samples from the posterior of every parameter and also the forecasted energy demand. You can see that it really picks up on the bi-annual seasonality. There is also a noticeable upward trend. Below, we display the mean of our predictive samples, along with the highest density interval. The light blue band indicates there is a 94% chance the observations fall in that range.
PyMC is a very expressive language. Model components are composable and exchangeable. You can mix and match likelihoods with different predictors or functional forms. The model we’ve described does a decent job of capturing the main dynamics of electrical demand. But we could extend:
- If you are modeling multiple regions, you can use hierarchical priors so the model learns commonalities between regions to inform the parameter estimates of each region. The model can be designed to capture correlations across energy demand in different regions. In turn, it can give us the same variety of rich uncertainty quantification in each region.
- The periodic components might not follow a strict pattern. Perhaps climate change speeds up the transitions between seasons over time. In that case, the structure of the period function changes over time in ways that are hard to represent with parametric models alone. In that case, PyMC offers a family of Gaussian processes that can learn parts of their functional form from the data while obeying constraints informed by our domain knowledge, such as the expectation that these effects should be roughly periodic.
Ontario’s grid is powered by a mix of sources, each with distinct costs and capacity factors.
They also have ambitious clean energy targets. The optimization model will then include a constraint that enforces a minimum percentage (e.g., 80%) from non-emitting sources.
PyMC: Uncertainty as Data
PyMC provides a full probability distribution of forecasts for the future. For the Ontario demand problem:- 4,000 posterior samples per forecast day (4 chains × 1,000 draws)
- 181 days forecast horizon (Jan-Jun 2026)
- Mean demand: 412,501 MWh
- 95th percentile: 483,507 MWh
FICO Xpress: Decision Making Under Uncertainty
Both the chance-constrained and CVaR models built in FICO Xpress below use the same input data, clean-energy requirement, and forecast scenarios generated from PyMC. However, they differ in how they translate forecast uncertainty into risk exposure, ultimately leading to different decisions.The chance-constrained model controls the frequency of failing to meet demand, while the CVaR model controls the severity of shortfalls in the most extreme but plausible shortage scenarios.
Which one to use in practice depends on the specific business objective, the organization’s risk tolerance, the relative importance of failure frequency versus failure severity, and the operational cost of being wrong.
In the words of economist Thomas Sowell, “There are no solutions, only tradeoffs.” The same is true when optimizing under uncertainty, where different modeling approaches emphasize different tradeoffs between cost, reliability, and risk.
FICO® Xpress Python API
Since PyMC is a Python-native probabilistic programming library for building Bayesian models, the FICO Xpress Python API is used to easily incorporate mathematical optimization into broader data science workflows.The Chance-Constrained Model
A chance-constrained model controls how often violations are allowed to occur.In this example, the chance-constrained model is used to ensure that planned electricity generation meets demand at least 95% of the time. This corresponds to using the 95th percentile of the forecasted demand distribution each day generated by PyMC.
Sets
Parameters
Decision Variables
Objective Function
The objective function minimizes total power generation cost across all power sources in the planning horizon to find the lowest cost plan.Constraints
The demand-satisfaction constraint requires planned generation to be at least as large as the β-th percentile of forecasted demand each day. In this example, β=0.95, so it ensures the model plans enough electricity generation to meet demand in 95% of forecasted scenarios each day.In two lines of code, the 95th percentile values are extracted from the PyMC scenarios to formulate the demand-satisfaction constraint.
The clean-energy constraint ensures that at least 80% of total power generation each day comes from clean energy sources.
The chance-constrained model simplifies uncertainty by collapsing the full forecasted demand distribution generated by PyMC into a single vector of 95th percentile demand values, one for each day in the planning horizon. This creates a clear and intuitive way to control how often planned generation is allowed to fall short of demand.
The CVaR Model
The CVaR model takes a different approach. Instead of distilling the entire forecast distribution into a vector of user-defined percentiles, the CVaR model uses the full set of forecast scenarios and converts them into a shortage-loss distribution based on the power generation decisions the model makes.This allows the model to go beyond controlling how often shortfalls occur to instead controlling how severe those shortfalls are in the most extreme scenarios.
Because CVaR explicitly penalizes the magnitude of shortages in extreme scenarios, it is often used for more risk-sensitive decision making and can lead to more conservative decisions and a higher cost than a chance-constrained model.
The specific formulation used below is the Rockafellar–Uryasev model. It was published in The Journal of Risk in 2000 in the paper “Optimization of Conditional Value-at-Risk.” This formulation helped make CVaR popular in practice because it is convex, interpretable, scenario-friendly, and often reducible to a linear optimization model.
Since the CVaR model is an extension of the chance-constrained model, only the new additions are listed below.
Sets
To reduce problem size, the Ω set could instead include a representative sample of demand scenarios for each day. The choice to use all or a subset of daily demand scenarios is ultimately left to the discretion of the modeler.
Parameters
The penalty cost parameter (p) should generally be set higher than the cost of the most expensive available power generation source so that the model prefers serving demand over leaving it unmet.
Since gas is the highest-cost source at $80/MWh:
- A low penalty of ~$100/MWh means shortages are undesirable, but the model may still tolerate shortages in extreme scenarios
- A moderate penalty of ~$250-$500/MWh makes shortages much more expensive than dispatching gas, so the model will work harder to avoid them
- A high penalty of ~$1,000+/MWh makes shortages extremely costly and pushes the model toward very conservative solutions
A higher shortage penalty can make the clean-energy requirement more expensive to satisfy, increasing the magnitude of the clean energy constraint’s shadow price when the constraint is binding.
The λ parameter controls how much weight the model places on CVaR risk relative to ordinary power generation cost. When λ=0 tail risk is ignored entirely. Larger λ values place progressively more emphasis on avoiding severe shortages in extreme scenarios. In practice, the appropriate value depends on the relative scale of the cost and CVaR terms in the objective function.
Rather than choosing one value for λ and solving the model once, it is common to solve the model for numerous values of λ to examine the cost-risk tradeoff.
Decision Variables
Together, the new decision variables, along with the α parameter, help the model identify the extreme tail of the shortage-loss distribution and measure how severe those tail outcomes are.
Objective Function
The objective function extends the chance-constrained objective function to minimize two things simultaneously. The first term is the total cost of generating electricity across all sources and days in the planning horizon, which is equivalent to the objective function in the chance-constrained model. On its own, that term tells the model to find the lowest-cost generation plan.The second term adds a CVaR risk penalty. That penalty measures the average severity of shortage costs in the most extreme α-fraction of the shortage-loss distribution. The λ parameter determines how strongly the CVaR tail risk influences the model’s decisions relative to power generation cost.
Constraints
The shortage constraint replaces the demand-satisfaction constraint from the chance-constrained model and defines shortage as the amount of demand that exceeds planned generation. In other words, if planned generation is sufficient, shortage equals zero, but if demand is higher than planned generation, the difference is the shortage (i.e., unmet demand).This set of constraints is where the PyMC demand forecast scenarios are incorporated.
The last new set of constraints measures how far each scenario’s total shortage cost exceeds the VaR threshold, z. This is the part of the Rockafellar-Uryasev formulation that identifies the shortage-cost scenarios that fall beyond the VaR threshold and contribute to the CVaR term in the objective.
Solving Both Models in FICO Xpress
Both the chance-constrained and CVaR models in this blog are linear programming (LP) models. FICO Xpress provides multiple algorithms for solving LPs, including primal simplex, dual simplex, barrier, and PDHG. In Xpress 9.8, a GPU-accelerated PDHG algorithm is also available for NVIDIA GPUs as a beta feature.However, in practice, chance-constrained and CVaR models are not limited to LPs. Generation planning models often include binary unit commitment decisions, startup and shutdown costs, ramping limits, minimum up/down times, reserve requirements, transmission constraints, storage, and other operating restrictions. Those additions often turn otherwise simple chance-constrained or CVaR formulations into MIP, QP, QCQP, MIQP, MIQCP, or conic optimization models.
This blog focuses on a simplified application to introduce how chance-constrained and CVaR models work. In practice, PyMC and FICO Xpress are built to accommodate much larger and more complex instances.
For example, AFRY’s BID3 platform uses FICO Xpress to influence billion-dollar energy investments across major European grid operators in the UK, Norway, Germany, and Denmark.
“Power systems around the world are undergoing an unprecedented transformation,” said Zeid Munir, Principal – Modeling Solutions at AFRY. “Long-term investment planning is becoming increasingly complex. We chose FICO’s optimization solution for its industrial-grade linear and mixed-integer programming capabilities and scalability across complex, multi-dimensional problems. No other solution on the market provided the tools we needed.”
Artelys’s TERRE platform uses FICO Xpress to balance power systems and ensure cost-efficient supply to over 300 million Europeans.
“With intermittent generation, the inaccuracy of generation and net demand forecasts will only grow in the coming years. The TERRE system will be able to adjust generation and demand faster, in larger volumes and closer to real time than has ever been done before,” said Michaël Gabay, director at Artelys. “This project highlights how FICO Xpress Optimization technology can be used in critical systems, impacting millions of people.”
Gabay goes on to highlight the importance of capturing the uncertainty from demand forecasts. “Deviations, especially those due to forecast errors, happen all the time,” said Gabay. “It is simply impossible to perfectly predict demand or intermittent generation. It is of utmost importance to be able to adjust generation and flexible demand in real-time.”
Results
The results below illustrate the core tradeoff between the two approaches.The CVaR model recommends generating ~8.5% more electricity on average each day. That increases total cost by about 22% but reduces the shortage rate from 5% to 0.35%. The tradeoff is explicit.
In other words, the CVaR model buys materially lower tail risk at a higher operating cost.
Pareto Analysis: Quantifying Policy Trade-offs
A Pareto frontier shows the set of best possible tradeoffs between two competing objectives. For chance-constrained and CVaR models, Pareto frontiers are useful because they make the tradeoff between total cost and risk explicit, helping decision-makers see how much additional cost is required to achieve greater protection against shortfalls.By varying the CVaR weight, λ, from 1-1000 and the clean energy policy from 80%-90%, different solutions can be evaluated and compared with each other:
If targeting 90% clean energy, the minimum shortage floors at 5.36%. In other words, clean capacity quickly becomes a binding constraint as it increases beyond 80%.
Key Insights for Decision-Makers
- Policy costs are quantifiable: Stricter clean energy targets limit peaking capacity, increasing shortage risk.
- Trade-offs are explicit: At 90% clean, minimum shortage is 5.36%; relaxing to 80% achieves 0.35% and costs $440M more.
- Pareto analysis: Decision-makers can see the entire cost-reliability landscape across different policy scenarios and risk attitudes.
Getting Started
Run the models in this blog yourself with PyMC and FICO Xpress: https://github.com/fico-xpress/xpress-community/tree/main/StochasticEnergyPlanningRun more optimization models in Python using FICO Xpress: https://github.com/fico-xpress/python-notebooks/tree/main/modeling_examples
Run more Bayesian applications in Python using PyMC: https://www.pymc.io/projects/examples/en/latest/gallery.html
Find the right FICO Xpress license for you: https://www.fico.com/en/fico-xpress-trial-and-licensing-options
Note: The CVaR model in this blog samples 1,000 demand scenarios, which exceeds the Xpress community edition limit. A free trial license is available at the link above and provides full solver capability. The chance-constrained model runs without restriction on the Community license.
Conclusion
PyMC and FICO Xpress are a powerful combination for decision-making under uncertainty. PyMC quantifies uncertainty; FICO Xpress optimizes under it. Together, they enable higher-quality, more robust decisions at scale that leaders respect and the field trusts.The next time you're tempted to use a point forecast in an optimization model, ask: “If this optimization model is going to fail in production, how is it going to fail?” In most real-world applications, the answer almost always lies in failing to accommodate the uncertainty inherent in the forecasting process itself.
By quantifying that uncertainty with PyMC and incorporating it into FICO Xpress, organizations can confidently make decisions that are more robust, more transparent, and better aligned with real-world operating conditions
Updated 7 months ago
Version 3.0FICO
Community Manager
Joined July 21, 2025
FICO® Xpress Optimization Blog
Follow this blog board to get notified when there's new activity