dual_problem = (f, xmin, xmax, ymin, ymax) => {
const g = lambda => -(lambda**2)/2 - lambda*a
const height = 240;
const width = 480;
const margin = {top: 20, right: 30, bottom: 20, left: 40};
const x = d3.scaleLinear().domain([xmin, xmax]).range([margin.left, width - margin.right]);
const y = d3.scaleLinear().domain([ymin, ymax]).range([height - margin.bottom, margin.top]);
const svg = d3.select(DOM.svg(width, height));
const a_x = Math.min(a, 0);
const p_star = f(a_x);
svg.append("g")
.attr("transform", `translate(0,${y(0)})`)
.call(d3.axisBottom(x).ticks(5,"f"));
svg.append("g")
.attr("transform", `translate(${x(0)},0)`)
.call(d3.axisLeft(y).ticks(5, "f"));
svg.append("path")
.attr("fill", "none")
.attr("stroke", 'red')
.attr("stroke-width", 2)
.attr("d", d3.line(d => x(d.x), d => y(d.y))([{x: xmin, y: p_star},{x: xmax, y: p_star}]));
svg.append("path")
.attr("fill", "none")
.attr("stroke", 'black')
.attr("stroke-width", 2)
.style("stroke-dasharray", ("3,5"))
.attr("d", d3.line(d => x(d.x), d => y(d.y))([{x: xmin, y: p_star},{x: xmax, y: p_star}]));
svg.append("path")
.attr("fill", "none")
.attr("stroke", 'black')
.attr("stroke-width", 2)
.attr("d", d3.line(d => x(d.x), d => y(d.y))(make_func_data(g, xmin, xmax)));
return svg.node();
}