The PCT Economics Model - Initializing and testing

from Adam Matic 2011.08.16.19.15 CET

Bill Powers (2011.08.04.0705 MDT)

Would you like a simple practice problem to work on just to get your feet wet?

Here’s one. A consumer wishes to have Rg amount of goods ("R"eference amount, subcategory "g"oods). The goods inventory already contains N units of goods. The goods cost Cg for each unit. The customer’s money inventory stands at M dollars to start with. Write a control system model for bringing N to the value Rg, by spending money from the inventory M. For various initial values of the variables, determine whether the desired amount of goods will be obtained. Don’t calculate it yourself; make the model show you the answer.

Hint: M is not allowed to go negative.

AM:
Ok, feet in the water. The ruby code is in the attachment.
I don’t like ruby very much. It was fun learning it, but I had a lot of trouble with the Tk GUI library while making the labels and buttons do what I want, and the main event loop which I just barely made work, and I’ll have no idea what to do if things get more complicated.

I’m considering transfering to some other language while the project is still small, but I’m waiting for my laptop to come from the repair shop. Apparently, the power circuits failed and it’s taking them quite a while to fix it. In the meantime, I’m using my roomate’s laptop for short periods of time when she is not on facebook. :smiley:

Anyway, I tried to make things as simple as possible, I hope I didn’t over-simplify the code for the control loop.
There is an “actor” with a single loop for controling the quantity of some good X by buying it from the shop. The shop is a simple container of variables, no control loops yet.

Initial variables can be changed in code. The program runs until the actor reaches Rg or is out of money.
By clicking the two buttons “take 1” or “give 1” a user can act as a disturbance by adding or removing one unit of money from the actor.

Standing by for comments.

ecmodel.rb (2.16 KB)

···

The smallest next step, other then fixing errors, I assume, is adding another shop. It would tacke the problem of ‘choosing’. If all else is equal, a person will allways choose a cheaper good. (?) Since all else is rarely equal, we don’t see that law very much. Perhaps one shop is closer to the other, or smells nicer, or our friend works there, or there is some other need being met.


ps. for anyone interested, ruby can be downloaded from: http://www.ruby-lang.org/en/downloads/
make sure to check the ‘tcl/tk’ check box before starting the installation, those are for the GUI libraries

Best, Adam

[From Bill Powers (2011.08.17.0410 MDT)]

Adam Matic 2011.08.16.19.15 CET --

AM: Ok, feet in the water. The ruby code is in the attachment.
I don't like ruby very much. It was fun learning it, but I had a lot of trouble with the Tk GUI library while making the labels and buttons do what I want, and the main event loop which I just barely made work, and I'll have no idea what to do if things get more complicated.

I'm considering transfering to some other language while the project is still small, but I'm waiting for my laptop to come from the repair shop. Apparently, the power circuits failed and it's taking them quite a while to fix it. In the meantime, I'm using my roomate's laptop for short periods of time when she is not on facebook. :smiley:

BP: This may be an opportunity to try Lazarus, which is (almost) a clone of Delphi. It's free (GNU) and eventually will have full functionality. The visual GUI is fine, using forms to set up screens and controls, so all the TK stuff is unneccessary. And the programs are FAR more readable. Alternatively, you might try the more finished Delphi XE Starter Edition which is available from Embarcadero for $200 (licensed for no more than $1000 annual revenues from use of program). I have both Lazarus and Delphi XE installed on my desktop, so would be able to run and contribute to your programs. As the first officer on the scene of this crime, it's your case.

Anyhow, I was able to read your code enough to understand what it does, though I couldn't have written it.

Anyway, I tried to make things as simple as possible, I hope I didn't over-simplify the code for the control loop. There is an "actor" with a single loop for controling the quantity of some good X by buying it from the shop. The shop is a simple container of variables, no control loops yet.

The actor's control loop looks fine. Every control loop requires one integrator in it for stability (and no more than one), which is a much simplified version of stability requirements but it works. In your code the control system shows up in this loop:

step = cs.Step(a_goodx).round(2)
a_goodx = (a_goodx + step).round(2)

... with the required integration in the second statement. I assume that "round(2)" limits the variable to 2 decimal places of accuracy?? The control system is defined in the method "Step", containing perceptual signal, reference signal, gain, and output quantity.

You have dt set to 0.001 and a_gain set to 600, which is almost too much gain but fortunately just small enough to let the system settle down. Try reducing it to 200. That should give a nice smooth approach to equilibrium.

I suggest that you go on developing the actor further before adding more shops. Give the actor an income, which adds to a_money on every iteration (or 7th or 30th if pay arrives intermittently). Give the actor an assortment of goods to want. Assign different loop gains to the consumer's control of different goods, and different reference levels, as well as different prices. Add a rate of use or depreciation for the goods, so they gradually disappear from a_goodx and have to be replaced. This will allow the program to iterate continuously instead of stopping, so you can print out the values of variables and watch them change with time.

With that much you can play with changing prices, quantities wanted, and importances of the goods (output gains) and see the effects on where the system comes to equilbrium. That should be interesting. You should see things like the law of supply and demand (at least on the demand side) without needing any special assumptions. Assuming the system is income-limited, you can change prices on one good and watch consumption change in all the goods. You can also add a control system for how much money is to be maintained in a-money -- either a specific amount, or a one-way system controlling for "no less than" some specific amount. It operates by changing reference levels for goods, or by directly conflicting with goods acquisitions at the level of making purchases (by saying "spend no more on that luxury").

It's VERY IMPORTANT to show all variable magnitudes continually so you can see what's going on.

Have fun.

Best,

Bill P.

[From Adam Matić 2011.08.19.1045 CET]

Bill Powers (2011.08.17.0410 MDT)

This may be an opportunity to try Lazarus, which is (almost) a clone of Delphi. It’s free (GNU) and eventually will have full functionality.

AM:
Sounds good. I’ll try it out.

BP:

The actor’s control loop looks fine. Every control loop requires one integrator in it for stability (and no more than one), which is a much simplified version of stability requirements but it works. In your code the control system shows up in this loop:

step = cs.Step(a_goodx).round(2)

a_goodx = (a_goodx + step).round(2)

… with the required integration in the second statement. I assume that “round(2)” limits the variable to 2 decimal places of accuracy?? The control system is defined in the method “Step”, containing perceptual signal, reference signal, gain, and output quantity.

AM:

So I added an integrator without knowing what it is. Good.

BP:

I suggest that you go on developing the actor further before adding more shops. Give the actor an income, which adds to a_money on every iteration (or 7th or 30th if pay arrives intermittently). Give the actor an assortment of goods to want. Assign different loop gains to the consumer’s control of different goods, and different reference levels, as well as different prices. Add a rate of use or depreciation for the goods, so they gradually disappear from a_goodx and have to be replaced. This will allow the program to iterate continuously instead of stopping, so you can print out the values of variables and watch them change with time.

AM:

Great, that’ll be the be the next step. I had this idea of having to make a large, table-sized, detailed blueprint of every loop and item that will go in the model, before any programming could be done. This one step at a time process made things start moving. Thank you for the suggestion.

I’ll get back with the next version.

Best

Adam