a two commodity model of economic choice

CSGfolk,

I've been following the recent discussions on the CSGnet with interest. As
some of you may recall I ceased my active participation in discussions on
the net after Bill Powers charged me among other things with having too
little respect for his Father's economics. One of the things that I
objected to then was Bill's expectation that was going to peddle his
economic model to the economic profession. Since, the model was intended
to demonstrate the correctness of his father's 'leakages' thesis which I regarded as too obviously flawed to be at all plausible, I had no interest
in continuing my participation on the CSGnet. Not when Bill was characterizing me as "bent" and "incompetent." I didn't at the time feel inclined to characterize the 'leakages' model as a "ignorant crankish
scheme." But, Bill was of the opinion that that was what I thought.
Perhaps not much has changed, but the recent discussion has encouraged me
to post the following description of a simple control theory model of a consumer.

One of the chief differences between this model of choice (based upon
control theory) and the orthodox model is that the control theory
based model doesn't assume that a consumer would consume an unlimited
quantity of a commodity if the price of the commodity fell to zero.

After all if pizza was free, would you order a billion boxes of pizza?
I don't think I would. What ever would I do with them when they were
delivered?

So, the simulation starts with the consumer consuming all of the first
commodity ( product A ) that is desired, which is a finite amount and
having just enough money to pay for this level of consumption.

Initially the price of commodity B is assumed to be infinite. So, the
consumer doesn't consume very much of commodity B. Then the price of
commodity B is lowered in steps till it is zero. As the price of B is
lowered the consumer begins to purchase larger and larger quantities of
good B. At first this results in the consumer purchasing less of good A.
However, a point is reached at which the price of good B has fallen
sufficiently that it becomes possible for the consumer to begin
purchasing more of good A. Of course when the price of good B falls to
zero, the consumer can have as much of B as is desired, and the entire
budget can again be spent on good A. At this point the consumer's
'tension' involved in choosing between the two commodities goes away.

The plot of the consumer's reaction to the price reduction of good B
is approximately thus:

       o o

        o o
         o
          o o
            o
              o o
                o
                    o o
                      o
  A o o
  > o
  >
  q
       quantity of good B --->
       > >
       > >
       price B infinite price B zero

   The lowercase 'o's in the plot represent quantities of A and B
   in a two dimensional plot.

I've modeled the two commodities as if they were equally desired.
Desired being defined in terms of their identical control loops.
It would be easily possible to modify the two commodities control
loops and generate a different consumption pattern. But, I would
expect that the overall pattern would remain basically the same.
a roughly U shaped price consumption pattern.

The mix of quantities that the consumer chooses is a result of a
constrained choice made in which there is a desire for each good.
And the desire is modeled as a control loop. And the choice is
in addition constrained by a limited budget.

I found modeling even this simple situation involved some unanticipated
complexity. After modeling a consumer's demand for one commodity, I
initially thought that it would be possible to create a combined system
in which there were three control loops for A, B and the budget.
However, I found that while I was able to get such a system running
it would only run within a very limited range. Exceed the range and
the system would either not model the consumer's behavior-- that is
not stay even close to the budget constraint, or the system would
blow-up because of various sorts of instabilities. In order to make
the system function in a plausible manner--that is over a reasonable
range of budgets, and reasonably close to the full range possible
for the two commodities I had to modify the loops by inserting what
amount to automatic gain controls. In the program below, those
familiar with Pascal will see that in the line from the consumption
loop:

iA := eA * gA * priceB/priceA * budget/MaxB;

the gain term is modified by the ratio of priceB/priceA, and the
ratio between the current budget and a Max Budget. Without the
adjustment these terms apply the system would only run within a
comparatively slight range.

On the budget side of the loop a similar compensation is required.

iPa := ePa * gPa * priceA/priceB * budget/MaxB ;

Beyond this those who can read Pascal will see that there is quite
a bit of local feedback, or several levels of feedback, which are
required to give the system a plausible range of operation. And,
even these measures are not sufficient to generate a system that
is stable, or will compute an output in a reasonable time when the
price of B is extremely large or close to zero. However, over
most of the range 99 percent or so, the program works well and
generates values which are very close to being error free. That
is the consumer spends very close to and not very much over the
budget ( usually within a fraction of a percent ). In the current
version of the program to achieve this accuracy it is necessary to
press the space key to allow enough repetitions to achieve the
attainable accuracy. The press 'A' or 'a' to restart the loop
calculations.

As it is, I think the program demonstrates in a plausible way one
of the implications of a shift from a conception of consumer behavior
based upon maximization to a consumer modeled as a control process.
That is chiefly that it isn't necessary to assume that a consumer
will want an infinite amount of a commodity if the price is zero.

I have no doubt that the program below could be substantially
improved. I may contain mistakes as a result of my limited
comprehension of what is actually going on as the code runs. But,
I like what I perceive in the structure of the code of the inter-
weaving of local and global feedback, and the gain-stabilization
features. I find the modest level of complexity required to make
even the most basic simulation of a two commodity case work
facinating. And, even in the two commodity case, I suspect that
there is more actually much more involved than is included in the
model.

I would suspect that a consumer's reaction to a price change
involves an element of learning, but there is nothing about
learning included in the model.

For the time being the program represents a point which is at,
or even beyond, what I can understand myself with much confidence.
There are some features included that look to me as if they are
upside down, but the code works the way it is rather than the
way I think it ought to be. In the future it might not be all
that difficult to expand the program to a three commodity case.
However, I'm more interested in questions that might provide
more insights into the application of control theory to economic
issues, and I am doubtful about what a three commodity case, or
an N commodity case would disclose.

Recently when the model was presented at a seminar, a senior
professor was sufficiently disturbed to begin shouting that such
models were entirely beside the point. And, for the immediate
time being I guess they are.

One of the practical demonstrations that such methods are for the
time being not considered important is the way in which university
computer facilities routinely block the transmission of EXE files.
This makes communication of such work difficult. I've found some
time ago that I using university email I couldn't receive EXE files
recently I found that attempts to send EXE files were also blocked.
So it goes.

Ref:

David Berlinski 2OOO _The Advent of the Algorithm_ New York: Harcourt

  Berlinski, who is also the author of _A Tour of the Calculus_ argues
  that the arrival of the computer has generated a shift in analysis
  from the methods of classical mathematics to computationally intensive
  methods. The program below uses 24000 repetitions to compute a new
  value for the quantities of A and B commodities. This might be
  drastically reduced by a more efficient program. But the point is,
  I think, that the program works reasonably well. And, it is an
  analysis that would I think be quite difficulty for even a very
  able mathematician to generate using classical methods. And, perhaps
  the best evidence for this conclusion is that despite more the more
  than thirty volumes of a "Control Theory Journal of Economics" the
  people publishing there haven't developed the insights I think are
  basic to a control theory approach to economics-such as the Giffen
  effects and now the possibility of considering a consumer who doesn't
  demand an infinite amount if the price is zero.

Herbert A Simon 1952 "On the Application of Servomechanism Theory in
the Study of Production Control" Econometrica, Vol 2O, No. 2.
(April, 1952) pp. 247-268.

   The clouds of integrals that fly like snow in Simon's paper on the
   theory analysis of the production and accumulation of ONE commodity
   illustrates, I think, the argument that Berlinski makes that the
   shift computers and algorithms represents a drastic intellectual
   change in scientific methods.

program November28; { was C2.pas version 1 }
  uses dos, crt, graph, grutils;
    const
     MaxB = 9000;
     slow = 500; { was 8000, 2000 }
     rep = 24000;
  var
    Exp_A, Exp_B, sta,stb, ie, be, eA, rA, p1, gA, iA, oA, Sa : real;
    ePa, rPa, pPa, gPa, iPa, oPa, Spa, priceA, oAt, oTa, eB, rB : real;
    gB, iB, oB, Sb, total, ePb, rPb, pPb, gPb, iPb, oPb : real;
    i, oeb, C, Change, Expenditure, Budget, Spb, priceB, oBt, oTb : real;
old_ota_d, old_oTb_d, old_i, old_oTa, old_oTb, old_priceA, old_priceB, old_budget : real;
     cycle, x, kount, count : integer;
     switch, first : boolean;
     key : char;
     Exp_At, Exp_Bt, QA_txt, QB_txt, budget_text, error : string[8];
     bt, Budget_txt, spriceA, spriceB : string[8] ;
begin
     initgraphics;
     switch := FALSE;
     clearviewport;
     first := TRUE;
     priceA := 270;
     priceB := 30;
     iA := 0; iB := 0; { intermeadiate term }
     oA := 0; oB := 0; { output A, B consumption loop }
     oAt := 0; oBt := 0; { output + expenditure output A,B }
     rPa := + 0; rPb := + 0; { local reference budget A, B }
     iPa := 0; iPb := 0; { intermeadiate term local budget }
     gPa := 8; gPb := 8; { gain local budget }
     old_priceA := 1;
     old_priceB := 1;
     old_budget := 1;
     budget := 9000; { was 9000 }
     rA := + 300; Rb := + 300;
     gA := 4; gb := 4; { was 20, 30, 50 , 5 }
     Sa := slow; Sb := slow; { was 1000 } { slowing factor consumption }
     gPa := 3; gPb := 3; { gain local budget }
     Spa := slow; Spb := slow; {was 500} { slowing factor local budget}
     cycle := 0; { delays display }

  repeat
      inc(cycle);
    { Outer Loop }
       old_oTa := oTa;
       old_oTb := otb;

       { Main computational loop }
For x := 1 to rep do { compile for use on modern machine using 4000 }
     begin
  { Consumption loop A }
         eA := rA - oTa ;
         iA := eA * gA * priceB/priceA * budget/MaxB;
         oA := oA + (iA - oA)/Sa ;
   { Local budget loop }
         ePa := rPa - oTa ;
         iPa := ePa * gPa * priceA/priceB * budget/MaxB ;
         oPa := oPa + (iPa - oPa)/Spa;
         oTa := oA + i * oPa * priceA;

    { Loop B }

         eB := rB - oTb;
         iB := eB * gB * priceA/priceB * budget/MaxB;
         oB := oB + (iB - oB)/Sb ;

{ Local Budget loop B }
        ePb := rPb - oTb;
        iPb := ePb * gPb * priceA/priceB * budget/MaxB ;
        oPb := oPb + (iPb - oPb)/Spb ;
        oTb := oB + i * oPb * priceB ;

{ Budget Loop }
        Expenditure := oTa * priceA + otb * priceB; { budget }
        be := expenditure - budget; { budget error }
              { integrating Term }
        i := i + (be - i) /10000000 ; { integrating for budget error }

       { budget integrator: the budget error term 'be' is multiplied }
       { by constant gain term substracted by current integration term }
       { divided by stablization constant. This value is added to the }
       { current integration value 'i'. The integration term is added }
       { into the local budget loops. }
   end; { of for loop to calculate values for commodites A and B }

  setcolor(black);
  outtextXY(150,440,spriceA);
  outtextXY(150,460,spriceA);
  outtextXY(335,440,qA_txt);
  outtextXY(335,460,qB_txt);
  outtextXY(550,420,exp_At);
  outtextXY(550,440,exp_Bt);
  outtextXY(550,460,Bt);
  setcolor(lightgray);
  str(oTa:3:2,qA_txt);
  outtextXY(220,440,'Quantity A = ');
  outtextXY(335,440,qA_txt);
  str(oTb:3:2,qB_txt);
  outtextXY(220,460,'Quantity B = ');
  outtextXY(335,460,qB_txt);
  str(PriceA:3:2,SpriceA);
  outtextXY(50,440,'price A = ');
  outtextXY(150,440,spriceA);
  str(PriceB:3:2,SpriceB);
  outtextXY(50,460,'price B = ');
  outtextXY(150,460,SpriceB);
  exp_A := priceA * oTa;
  exp_B := priceB * oTb;
  str(Exp_A:3:2,Exp_At);
  outtextXY(450,420,'Exp A = ');
  outtextXY(550,420,exp_At);
  str(Exp_B:3:2,exp_Bt);
  outtextXY(450,440,'Exp B = ');
  outtextXY(550,440,exp_Bt);
  total := exp_A + exp_B;
  str(total:3:2,Bt);
  outtextXY(450,460,'Budget = ');
  outtextXY(550,460,Bt);

    { ### }
       line(1,round(- budget + 400),15,round(- budget + 400));

   if cycle > 0 then
    begin
       setcolor(brown);
       line(round(oTa),round(- oTb + 400),
       round(old_oTa_d),round(- old_oTb_d + 400));
     end;
      old_oTa_d := oTa;
      old_oTb_d := oTb;
       setcolor(lightblue);
       circle(round( oTa),round( - OTb + 400 ) ,2);
       setcolor(lightgray);
       line(1,400,round(Ra + 100),400 );
       line(1,400,1, 10);
       line(1,400,round(Ra),400 - round(Rb) );
       putpixel(round(Ra),400 - round(Rb),yellow);
       setcolor(yellow);
       line(round(Ra),400,round(Ra),385);
       line(1,round(400 - Rb),15,round(400 - Rb));
       if cycle > 0 then
         begin
           setcolor(brown);
           line(round(oTa), round(-oTb + 400), round(old_oTa), round(-old_oTb + 400));
          end;
    if keypressed then key := readkey;
    if ( key in ['a','A'] ) and ( cycle > 3 ) then
        begin
         if first = TRUE then begin
            clearviewport;
            for x := 1 to 300 do { second value must be changed manually ### }
        begin
           if round((-(Budget-x * priceA)/priceB + 400)) < 400 then
           putpixel(x,round((-(Budget-x * priceA)/priceB)+400),magenta);
        end;
            setcolor(yellow);
            circle(round( oTa),round( - OTb + 400 ) ,2);
            first := FALSE;
          end;
     priceA := priceA/1.125;
            for x := 1 to 300 do { second value must be changed manually ### }
        begin
           if round((-(Budget-x * priceA)/priceB + 400)) < 400 then
           putpixel(x,round((-(Budget-x * old_priceA)/old_priceB)+400),black);
        end;
            for x := 1 to 300 do { second value must be changed manually ### }
        begin
           if round((-(Budget-x * priceA)/priceB + 400)) < 400 then
           putpixel(x,round((-(Budget-x * priceA)/priceB)+400),magenta);
        end;
      end;
      old_priceA := priceA;
      old_priceB := priceB;
      old_budget := budget;
if ( priceB >= priceA ) then
      for x := 1 to 300 do { second value must be changed manually ### }
        begin
            if round((-(Budget-x * priceA)/priceB + 400)) < 400 then
           putpixel(x,round((-(Budget-x * priceA)/priceB)+400),magenta);
        end;
      setcolor(yellow);
      line(round(Ra),400,round(Ra),385);
      line(1,round(400 - Rb),15,round(400 - Rb));
    setcolor(lightred);
    line(1,round(- budget/priceB + 400 ),8,round(- budget/priceB + 400 ));
  setcolor(lightgray);
  outtextXY( 10, 30, 'Two Commodity Case with Saturation for commodity A');
  outtextXY( 20, 50, 'C.TP\NOV28B.PAS 28 November 2003');
  outtextXY( 20, 70, 'Start decreasing the price of good B by pressing A/a.');
  setcolor(lightred);
  outtextXY( 20, 70, 'Start');
  setcolor(lightgray);

until key in ['Q','q'];
  closegraph;
end.

Bill williams
UMKC

[From Bill Powers (2003.11.30.1002 MST)]

Bill Williams (2003.11.30) --

CSGfolk,

I've been following the recent discussions on the CSGnet with interest. As
some of you may recall I ceased my active participation in discussions on
the net after Bill Powers charged me among other things with having too
little respect for his Father's economics. One of the things that I
objected to then was Bill's expectation that was going to peddle his
economic model to the economic profession. Since, the model was intended
to demonstrate the correctness of his father's 'leakages' thesis which I
regarded as too obviously flawed to be at all plausible, I had no interest
in continuing my participation on the CSGnet. Not when Bill was
characterizing me as "bent" and "incompetent." I didn't at the time feel
inclined to characterize the 'leakages' model as a "ignorant crankish
scheme." But, Bill was of the opinion that that was what I thought.
Perhaps not much has changed, but the recent discussion has encouraged me
to post the following description of a simple control theory model of a
consumer.

I take it that this means you would rather I stayed out of the discussion
of your model. OK.

Best,

Bill P.