Vimos que la forma más elemental de describir el comportamiento del consumidor es con teoría de elección
Conjunto \(X\) de alternativas (factibles y no factibles)
Preferencias \(\succsim\) sobre \(X\)
Conjunto de elección \(B\) de alternativas factibles (subconjunto de \(X\))
Describimos diferentes propiedades que pueden tener las preferencias
Preferencias
Racionalidad consiste en dos propiedades:
Completitud. Toda canasta en \(X\) se puede comparar con cualquier otra.
Transitividad. Si \(x\) es tan bueno como \(y\) e \(y\) tan bueno como \(z\), entonces \(x\) es tan bueno como \(z\).
Monotonicidad (débil). Si \(y\) tiene más de todos los bienes que \(x\), \(y\) es mejor que \(x\).
Monotonicidad estrícta (fuerte). Si \(y\) tiene al menos tanto de todos los bienes que \(x\) y más de al menos uno, \(y\) es mejor que \(x\).
No saciedad local. En cualquier “entorno” alrededor de una canasta, siempre hay una canasta mejor.
Convexidad. Canastas intermedias son al menos tan buenas.
Convexidad estricta. Canastas intermedias son mejores.
Utilidad
Si las preferencias son racionales (y solo si lo son) podemos representarlas con una función de utilidad
Una función de utilidad para \(\succsim\) es una función \(u:X \to \mathbb{R}\) tal que
\(u(x) \geq u(y)\) si y solo si \(x \succsim y\).
Se desprende de la definición que…
\(u(x) > u(y)\) si y solo si \(x \succ y\).
\(u(x) = u(y)\) si y solo si \(x \sim y\).
Curvas de indiferencia
Curvas de indiferencia
Supongamos un contexto de dos bienes: \(X = \mathbb{R}^2_+\).
Una forma de ver la relación entre diferentes canastas es con curvas de indiferencia.
Definición (Curva de indiferencia)
La curva de indiferencia asociada al nivel de utilidad \(\tilde{u}\) es el conjunto de canastas \(x \in X\) tales que \(u(x) = \tilde{u}\).
Definición (Mapa de indiferencia)
Llamamos mapa de indiferencia a un gráfico con varias curvas de indiferencia.
Mapa de indiferencia
Un mapa de indiferencia es una representación 2D de la función de utilidad.
Ejemplo: curvas de indiferencia
Mapa de indiferencia
Ejercicio: sustitutos perfectos
Grafique en el cuadrante positivo del plano \((X, Y)\) un mapa de indiferencia para las preferencias dadas por la función de utilidad \[
U(X, Y) = 4X + 2Y.
\]
Implicación de transitividad
Transitividad implica que las curvas de indiferencia no se cruzan.
Si \(x \sim y\) y \(y \sim z\), entonces \(x \sim z\).
Pero si \(x\) y \(z\) están sobre curvas de indiferencia diferentes, entonces \(x\succ z\) o \(z\succ x\).
Curvas de indiferencia no se cruzan
Curvas de indiferencia no se cruzan
Preferencias “well-behaved”
Preferencias monótonas y convexas
Convexidad no estricta
Preferencias monótonas y convexas
Ejercicio: curvas de indiferencia
Identifique las propiedades de las preferencias representadas por cada mapa de indiferencia.
Apéndice
Combinación Convexa
Arrastre los puntos \(A\) y \(B\) y ajuste el valor de \(\alpha\) para ver cómo cambia la combinación convexa \(Z = \alpha A + (1-\alpha) B\).
// Visualization with integrated alpha slider in sidebarviewof vizWithControls = {// Main containerconst container =document.createElement("div"); container.style.display="flex"; container.style.width="100%"; container.style.justifyContent="space-between"; container.style.alignItems="flex-start";// Theme colors from SCSSconst themeColors = {background:"#ffffff",foreground:"#222222",accent:"#FF3E00",lightGray:"#e5e5e5",mediumGray:"#9e9e9e",darkGray:"#555555" };// Plot areaconst plotArea =document.createElement("div"); plotArea.style.width="80%";// Control panelconst controlPanel =document.createElement("div"); controlPanel.style.width="20%"; controlPanel.style.padding="10px"; controlPanel.style.backgroundColor= themeColors.lightGray; controlPanel.style.borderRadius="4px"; controlPanel.style.fontSize="0.9em"; controlPanel.style.color= themeColors.foreground; controlPanel.style.fontFamily="Inter, -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', Helvetica, Arial, sans-serif";// Create alpha slider directly in the control panelconst sliderContainer =document.createElement("div"); sliderContainer.style.marginBottom="15px";const sliderLabel =document.createElement("label"); sliderLabel.textContent="α: "; sliderLabel.htmlFor="alpha-slider"; sliderLabel.style.marginRight="8px"; sliderLabel.style.fontWeight="500"; sliderLabel.style.color= themeColors.foreground;const slider =document.createElement("input"); slider.type="range"; slider.id="alpha-slider"; slider.min="0"; slider.max="1"; slider.step="0.01"; slider.value=0.5;// Default value slider.style.width="80%"; slider.style.marginBottom="5px"; slider.style.accentColor= themeColors.accent;const valueDisplay =document.createElement("span"); valueDisplay.textContent="0.50"; valueDisplay.style.marginLeft="5px"; valueDisplay.style.fontWeight="500"; sliderContainer.appendChild(sliderLabel); sliderContainer.appendChild(document.createElement("br")); sliderContainer.appendChild(slider); sliderContainer.appendChild(valueDisplay);// Store alpha in a variable that can be updated from our custom sliderlet alphaValue =0.5; slider.addEventListener("input",function() { alphaValue =parseFloat(this.value); valueDisplay.textContent= alphaValue.toFixed(2);updateVisualization(); container.dispatchEvent(newEvent("input"));// Notify Observable of change });// Initial positionslet pointA = [200,100];let pointB = [600,250];// Convert between pixel coordinates and data coordinatesfunctiontoDataCoords(px, py) {return [ xScale.invert(px), yScale.invert(py) ]; }functiontoPixelCoords(dx, dy) {return [xScale(dx),yScale(dy) ]; }const svg = d3.create("svg").attr("width",700).attr("height",350).style("font-family","Inter, -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', Helvetica, Arial, sans-serif");// Create scales for the axesconst xScale = d3.scaleLinear().domain([0,10]).range([40,660]);const yScale = d3.scaleLinear().domain([0,6]).range([310,20]);// Create axesconst xAxis = d3.axisBottom(xScale);const yAxis = d3.axisLeft(yScale);// Style the axes svg.append("g").attr("transform",`translate(0,310)`).attr("color", themeColors.darkGray).call(xAxis); svg.append("g").attr("transform",`translate(40,0)`).attr("color", themeColors.darkGray).call(yAxis);// Add axis labels svg.append("text").attr("x",350).attr("y",345).attr("text-anchor","middle").attr("fill", themeColors.darkGray).style("font-weight","500").style("font-size","14px").text("X"); svg.append("text").attr("transform","rotate(-90)").attr("x",-175).attr("y",15).attr("text-anchor","middle").attr("fill", themeColors.darkGray).style("font-weight","500").style("font-size","14px").text("Y");// Add a subtle grid svg.append("g").attr("class","grid").attr("transform",`translate(0,310)`).call(xAxis.tickSize(-290).tickFormat("")).selectAll("line").attr("stroke", themeColors.lightGray).attr("stroke-opacity",0.5); svg.append("g").attr("class","grid").attr("transform",`translate(40,0)`).call(yAxis.tickSize(-620).tickFormat("")).selectAll("line").attr("stroke", themeColors.lightGray).attr("stroke-opacity",0.5);// Remove grid border svg.selectAll(".domain").attr("stroke", themeColors.darkGray);// Data coordinates for the pointslet dataA =toDataCoords(pointA[0], pointA[1]);let dataB =toDataCoords(pointB[0], pointB[1]);let dataZ = [ alphaValue * dataA[0] + (1- alphaValue) * dataB[0], alphaValue * dataA[1] + (1- alphaValue) * dataB[1] ];// Calculate pixel coordinates for Zlet pixelZ =toPixelCoords(dataZ[0], dataZ[1]);// Draw line between A and Bconst line = svg.append("line").attr("x1", pointA[0]).attr("y1", pointA[1]).attr("x2", pointB[0]).attr("y2", pointB[1]).attr("stroke", themeColors.mediumGray).attr("stroke-width",1).attr("stroke-dasharray","5,5");// Point A (draggable)const circleA = svg.append("circle").attr("cx", pointA[0]).attr("cy", pointA[1]).attr("r",8).attr("fill","#4285F4") // Google blue.attr("stroke", themeColors.background).attr("stroke-width",2).attr("cursor","move").call(d3.drag().on("drag",function(event) { pointA[0] =Math.max(40,Math.min(660,event.x)); pointA[1] =Math.max(20,Math.min(310,event.y)); dataA =toDataCoords(pointA[0], pointA[1]);updateVisualization(); }));// Point B (draggable)const circleB = svg.append("circle").attr("cx", pointB[0]).attr("cy", pointB[1]).attr("r",8).attr("fill","#0F9D58") // Google green.attr("stroke", themeColors.background).attr("stroke-width",2).attr("cursor","move").call(d3.drag().on("drag",function(event) { pointB[0] =Math.max(40,Math.min(660,event.x)); pointB[1] =Math.max(20,Math.min(310,event.y)); dataB =toDataCoords(pointB[0], pointB[1]);updateVisualization(); }));// Point Z (convex combination)const circleZ = svg.append("circle").attr("cx", pixelZ[0]).attr("cy", pixelZ[1]).attr("r",8).attr("fill", themeColors.accent).attr("stroke", themeColors.background).attr("stroke-width",2);// Labelsconst labelA = svg.append("text").attr("x", pointA[0] +12).attr("y", pointA[1] -8).attr("fill", themeColors.foreground).style("font-weight","600").style("font-size","14px").text("A");const labelB = svg.append("text").attr("x", pointB[0] +12).attr("y", pointB[1] -8).attr("fill", themeColors.foreground).style("font-weight","600").style("font-size","14px").text("B");const labelZ = svg.append("text").attr("x", pixelZ[0] +12).attr("y", pixelZ[1] -8).attr("fill", themeColors.foreground).style("font-weight","600").style("font-size","14px").text("Z");// Update functionfunctionupdateVisualization() {// Recalculate Z in data coordinates dataZ = [ alphaValue * dataA[0] + (1- alphaValue) * dataB[0], alphaValue * dataA[1] + (1- alphaValue) * dataB[1] ]; pixelZ =toPixelCoords(dataZ[0], dataZ[1]);// Update line line.attr("x1", pointA[0]).attr("y1", pointA[1]).attr("x2", pointB[0]).attr("y2", pointB[1]);// Update circles circleA.attr("cx", pointA[0]).attr("cy", pointA[1]); circleB.attr("cx", pointB[0]).attr("cy", pointB[1]);// Update point Z circleZ.attr("cx", pixelZ[0]).attr("cy", pixelZ[1]);// Update labels labelA.attr("x", pointA[0] +12).attr("y", pointA[1] -8); labelB.attr("x", pointB[0] +12).attr("y", pointB[1] -8); labelZ.attr("x", pixelZ[0] +12).attr("y", pixelZ[1] -8);// Update control panelupdateControlPanel(); }// Function to update the control panelfunctionupdateControlPanel() {// Update the slider value (if it wasn't the source of the update)if (parseFloat(slider.value) !== alphaValue) { slider.value= alphaValue; valueDisplay.textContent= alphaValue.toFixed(2); }// Update the rest of the control panel infoconst coordsInfo =document.createElement("div");// Style for coordinate valuesconst valueStyle =`color: ${themeColors.foreground}; font-family: "SF Mono", Menlo, Consolas, Monaco, monospace; font-size: 0.9em;`; coordsInfo.innerHTML=` <div style="margin-bottom:10px; border-top: 1px solid ${themeColors.mediumGray}; padding-top: 8px;"> <strong style="color: #4285F4;">A:</strong> <span style="${valueStyle}">(${dataA[0].toFixed(2)}, ${dataA[1].toFixed(2)})</span> </div> <div style="margin-bottom:10px;"> <strong style="color: #0F9D58;">B:</strong> <span style="${valueStyle}">(${dataB[0].toFixed(2)}, ${dataB[1].toFixed(2)})</span> </div> <div style="margin-bottom:10px;"> <strong style="color: ${themeColors.accent};">Z:</strong> <span style="${valueStyle}">(${dataZ[0].toFixed(2)}, ${dataZ[1].toFixed(2)})</span> </div> <div style="margin-bottom:10px; border-top: 1px solid ${themeColors.mediumGray}; padding-top: 8px;"> <span style="color: ${themeColors.accent}; font-weight: 600;">Z</span> = <span style="color: #4285F4;">${alphaValue.toFixed(2)}A</span> + <span style="color: #0F9D58;">${(1-alphaValue).toFixed(2)}B</span> </div> `;// Clear previous coordinate info and append new infowhile (controlPanel.childNodes.length>1) { controlPanel.removeChild(controlPanel.lastChild); } controlPanel.appendChild(coordsInfo); }// Initial control panel setup controlPanel.appendChild(sliderContainer);updateControlPanel();// Set up value property for ObservableObject.defineProperty(container,"value", {get() {return alphaValue; } });// Append the SVG to the plot area plotArea.appendChild(svg.node());// Append everything to the container container.appendChild(plotArea); container.appendChild(controlPanel);return container;}