# Piecewise linear for a supply function

**URL:** <https://discourse.julialang.org/t/piecewise-linear-for-a-supply-function/130121>\
**Category:** Optimization (Mathematical)\
**Tags:** piecewise\
**Created:** [June 23, 2025, 7:11am UTC](https://discourse.julialang.org/t/piecewise-linear-for-a-supply-function/130121 "2025-06-23T07:11:24Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![nemoincognito](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nemoincognito/32/52395_2.png) [@nemoincognito](https://discourse.julialang.org/u/nemoincognito)\
**Post date:** [June 23, 2025, 7:11am UTC](https://discourse.julialang.org/t/piecewise-linear-for-a-supply-function/130121/1 "2025-06-23T07:11:24Z")

</div>

I am modelling costs for mines that have a fixed cost and a variable cost to slice the mine into realistic average costs for various levels of output.

```julia
mine_name = prod_capa_cost_df[100,:mine_name]
capacity = prod_capa_cost_df[100,:prod_capa_Mt]
price_ex_transp = prod_capa_cost_df[100,:price_ex_transp]
overhead_cost_usd_pt = prod_capa_cost_df[100,:overhead_cost_usd_pt]
println("Mine name: ",mine_name, " | Capacity:",capacity," | Price ex transp:", price_ex_transp, " | Overhead cost pt: ",overhead_cost_usd_pt)
#range = 2

d = Base.range(0.0,stop=capacity,step=5)
fd = overhead_cost_usd_pt*capacity .+ price_ex_transp.*d 
mc = fd./d

```

Output from the print statement:

Mine name: Inner Mongolia (East) KSOE Surface | Capacity:117.28656 | Price ex transp:1.79 | Overhead cost pt: 4.79700886965258

How does one use piecewise linear to approximate this function? Can you just break up the mine into “chunks” but how do you then require the highest cost segments are used first - the ones where the scale economies have not kicked in and you need higher output to realise lower costs?

Another option would be to put this in the problem statement:

> @objective(  
> cn\_coal\_model,  
> Min,  
> sum(r.total\_marginal\_cost \* r.supply\_item\_mass\_by\_node \* 1e6 + fixed\_costs \* ifelse(r\>0,1,0)\*1e6 for r in eachrow(df\_node\_data)) +  
> sum(r.transp\_cost\_tot\_usd \* r.mf \* 1e6 for r in eachrow(flowslist)) +  
> sum(r.pref\_para \* r.mf \* 1e6 for r in eachrow(flowslist)) +  
> sum(r.transm\_cost\_usd\_GJ \* 1e6 \* r.mf \* 1e6 \* r.CV\_PJ\_p\_Mt\_therm for r in eachrow(flowslist))

Are such ifelse statements allowed for problem statements that refer to a variable?

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [June 23, 2025, 8:08am UTC](https://discourse.julialang.org/t/piecewise-linear-for-a-supply-function/130121/2 "2025-06-23T08:08:52Z")

</div>

> [@nemoincognito](#):
>
> Can you just break up the mine into “chunks” but how do you then require the highest cost segments are used first - the ones where the scale economies have not kicked in and you need higher output to realise lower costs?

Yip. Something like this:

```julia
using JuMP
fixed_cost = 5.0
regular_cost = 1.0
overtime_cost = 1.5
regular_capacity = 10.0
overtime_capacity = 5.0
total_capacity = regular_capacity + overtime_capacity
model = Model()
@variable(model, 0 <= x <= total_capacity)
@variable(model, 0 <= x_regular <= regular_capacity)
@variable(model, 0 <= x_overtime <= overtime_capacity)
@constraint(model, x == x_regular + x_overtime)
@variable(model, z, Bin)
@constraint(model, x <= total_capacity * z)
@objective(
    model, 
    Min,
    fixed_cost * z + regular_cost * x_regular + overtime_cost * x_overtime,
)

```

> Are such ifelse statements allowed for problem statements that refer to a variable?

These are not allowed
