• Log InLog In
  • Register
Liquid`
Team Liquid Liquipedia
EST 11:48
CET 17:48
KST 01:48
  • Home
  • Forum
  • Calendar
  • Streams
  • Liquipedia
  • Features
  • Store
  • EPT
  • TL+
  • StarCraft 2
  • Brood War
  • Smash
  • Heroes
  • Counter-Strike
  • Overwatch
  • Liquibet
  • Fantasy StarCraft
  • TLPD
  • StarCraft 2
  • Brood War
  • Blogs
Forum Sidebar
Events/Features
News
Featured News
ByuL: The Forgotten Master of ZvT29Behind the Blue - Team Liquid History Book19Clem wins HomeStory Cup 289HomeStory Cup 28 - Info & Preview13Rongyi Cup S3 - Preview & Info8
Community News
Team Liquid Map Contest - Preparation Notice6Weekly Cups (Feb 23-Mar 1): herO doubles, 2v2 bonanza1Weekly Cups (Feb 16-22): MaxPax doubles0Weekly Cups (Feb 9-15): herO doubles up2ACS replaced by "ASL Season Open" - Starts 21/0258
StarCraft 2
General
Vitality disbanding their sc2-team How do you think the 5.0.15 balance patch (Oct 2025) for StarCraft II has affected the game? Team Liquid Map Contest - Preparation Notice ByuL: The Forgotten Master of ZvT Nexon's StarCraft game could be FPS, led by UMS maker
Tourneys
RSL Season 4 announced for March-April Sparkling Tuna Cup - Weekly Open Tournament $5,000 WardiTV Winter Championship 2026 Sea Duckling Open (Global, Bronze-Diamond) PIG STY FESTIVAL 7.0! (19 Feb - 1 Mar)
Strategy
Custom Maps
Publishing has been re-enabled! [Feb 24th 2026] Map Editor closed ?
External Content
The PondCast: SC2 News & Results Mutation # 515 Together Forever Mutation # 514 Ulnar New Year Mutation # 513 Attrition Warfare
Brood War
General
BSL 22 Map Contest — Submissions OPEN to March 10 BGH Auto Balance -> http://bghmmr.eu/ Flash's ASL S21 & Future Plans Announcement Gypsy to Korea BW General Discussion
Tourneys
ASL Season 21 Qualifiers March 7-8 [Megathread] Daily Proleagues [BSL22] Open Qualifier #1 - Sunday 21:00 CET Small VOD Thread 2.0
Strategy
Soma's 9 hatch build from ASL Game 2 Fighting Spirit mining rates Simple Questions, Simple Answers Zealot bombing is no longer popular?
Other Games
General Games
Path of Exile PC Games Sales Thread Nintendo Switch Thread Stormgate/Frost Giant Megathread Battle Aces/David Kim RTS Megathread
Dota 2
Official 'what is Dota anymore' discussion The Story of Wings Gaming
League of Legends
Heroes of the Storm
Simple Questions, Simple Answers Heroes of the Storm 2.0
Hearthstone
Deck construction bug Heroes of StarCraft mini-set
TL Mafia
Mafia Game Mode Feedback/Ideas Vanilla Mini Mafia TL Mafia Community Thread
Community
General
US Politics Mega-thread Russo-Ukrainian War Thread Mexico's Drug War Things Aren’t Peaceful in Palestine YouTube Thread
Fan Clubs
The IdrA Fan Club
Media & Entertainment
[Manga] One Piece [Req][Books] Good Fantasy/SciFi books Anime Discussion Thread
Sports
2024 - 2026 Football Thread Formula 1 Discussion TL MMA Pick'em Pool 2013
World Cup 2022
Tech Support
Laptop capable of using Photoshop Lightroom?
TL Community
The Automated Ban List
Blogs
FS++
Kraekkling
Shocked by a laser…
Spydermine0240
Gaming-Related Deaths
TrAiDoS
ONE GREAT AMERICAN MARINE…
XenOsky
Unintentional protectionism…
Uldridge
ASL S21 English Commentary…
namkraft
Customize Sidebar...

Website Feedback

Closed Threads



Active: 3342 users

Caller’s Tutorial: Economics, Part II

Blogs > Caller
Post a Reply
Caller
Profile Blog Joined September 2007
Poland8075 Posts
Last Edited: 2009-11-21 09:13:15
November 21 2009 05:07 GMT
#1
Part 1: http://www.teamliquid.net/blogs/viewblog.php?topic_id=106061

To those of you whom attempt to solve the Utility Maximization Problem, you will probably see something crazy like this:

Maximize U(x1, x2) s.t. M = p1x1 + p2x2
L = U(x1, x2) + λ(M-p1x1 + p2x2)
dL/dx1 = du/dx1 – λp1
dL/dx2 = du/dx2 – λp2
dL/d λ = M –p1x1 + p2x2


WTF???

Fortunately, I’ll help you take this apart. The idea of the above is called Lagrangian multipliers. It’s a way to optimize problems while avoiding as much butthurt as possible, unless you’re good at math, in which case you can probably derive an easier way to do this. Of course, if you’re good at math, you wouldn’t need my help to do this either, so good luck For those of us who aren’t gods among men, here’s an easier way to do this.

The first statement is this:

Maximize U(x1, x2) s.t. M = p1x1 + p2x2


This is simply stating that this is an optimization problem. It says the following in a sentence:
Find the maximum utility that somebody could get from purchasing a certain amount of two items (x1 and x2). However, they have a certain budget (M) that they can spend, and that each item has a price (p1, p2).

This is pretty obvious without the jargon: basically, what’s the most useful combination of things that you can buy with your money and their prices? You can pick how much you want of each kind-namely, you choose x1 and x2. These are what we call endogenous variables, because we are trying to figure those out. We don’t control p1, p2, and M (as those are external to our choice) so we call those exogenous variables.

The second statement is what we call the Lagrangian function. This is basically one of the easiest, most reliable ways to solve this problem. There is no such thing as a real life Lagrangian function-this is just us playing with the math in order to get a solution.

L = U(x1, x2) + λ(M-p1x1 - p2x2)


Now you may be wondering why the hell there is a lambda in our equation all of a sudden. The answer is that it is also a trick of math. Some people that are a lot smarter than I am and a lot better at math figured this out as a shortcut. I’m not going to bother doing the proof because I suck at proofs and I’m a lazy shit. Just pretend that it’s a formula or something.

In any case, we don’t know what lambda is, so we consider it a variable. However, we are trying to find our what we need for our two values, x1 and x2. To solve for them from this equation, we need to find a way to get them all together.

One very easy way is to simply take the partial derivatives of the Lagrangian function with respect to each endogenous variable. So…

dL/dx1 = du/dx1 – λp1
dL/dx2 = du/dx2 – λp2
dL/d λ = M –p1x1 - p2x2


The first expressions are us taking the Lagrangian function with the derivative. This is just mathematical trickery here. They are what we call First Order Conditions, or FOC, or FUUUUUUUUU~

However, we can figure out a little bit of what the hell is going on. We have two equations up there-namely, these two:

dL/dx1 = du/dx1 – λp1
dL/dx2 = du/dx2 – λp2


We want to figure out what x1 and x2 are, but we can’t really isolate them with the lambda present. Instead, we will do a little trick of math. Because this is an optimization problem, we can set the left side of the equation to be zero, so we get:

0 = du/dx1 – λp1
0 = du/dx2 – λp2


Now we set the two equations like this:

λp1= du/dx1
λp2 = du/dx2


Now how do we get rid of the lambda? Easy: we divide one equation by another.

λp1/ λp2= (du/dx1)/(du/dx2) = p1/p2


This happens to be the Marginal Rate of Substitution, or MRS, for those of you paying attention.

So what does this tell us? It tells us that it is possible to figure out what the best amount of x1 and x2 is, in terms of p1, p2, and M. This is called Marshallian Demand.
For instance, suppose our Utility function was U = (x1)(x2).
Then our first order conditions would be:

dL/dx1 = x2 – λp1
dL/dx2 = x1 – λp2
dL/d λ = M –p1x1 - p2x2


And we get:

p1/p2 = x2/x1
so x2 = p1x1/p2.


Now you may be suspicious here. There’s an x1 on the right side, which doesn’t seem to help us here. However, we can abuse math again (don’t try this with women) to get another expression. This time, we use the third equation, and set it to zero, and substitute for x2:

0 = M – p1x1 - p2(p1x1/p2)


And now we do basic math to get:

2p2x1 = M
X1 = M/(2p2)


And we plug this back in for x1 to solve x2,

X2 = p1(M/2p2)/p2, or p1M/(2p2^2)

And thus we have solved our Marshallian demand. If you want to get what those guys call the indirect utility function, simply plug x1 and x2 back into the original utility function. This gives us:

U = (x1)(x2)
U = (M/2p2)(p1M/2p2^2) = (p1M^2)/(4p2^3)


Next topic: The Price Effect and the Lagrangian.

post other things you may or may not want to see ^^


***
Watch me fail at Paradox: http://www.teamliquid.net/forum/viewmessage.php?topic_id=397564
paper
Profile Blog Joined September 2004
13196 Posts
Last Edited: 2009-11-21 05:12:15
November 21 2009 05:12 GMT
#2
oh man

aren't langrange multipliers from linear algebra? D:

bad memories
Hates Fun🤔
Gliche
Profile Blog Joined August 2008
United States811 Posts
November 21 2009 05:43 GMT
#3
yay econ!

can i ask how qualified you are to be teaching this, caller? ;D
KT fighting~!! | Designing things is fun!
AcrossFiveJulys
Profile Blog Joined September 2005
United States3612 Posts
November 21 2009 05:44 GMT
#4
lagrange theory is great =) I had to learn it in detail this semester, since we use it all the time in machine learning to derive data classifiers and regression functions.
pangshai
Profile Blog Joined January 2005
Chinatown5333 Posts
November 21 2009 06:16 GMT
#5
damn i was hoping this would be more for the interested layman, but its getting a bit too complex for me. good job with the tutorials though, i'm sure others will benefit!
#1 midas fan
Empyrean
Profile Blog Joined September 2004
17050 Posts
November 21 2009 06:34 GMT
#6
On November 21 2009 14:12 paper wrote:
oh man

aren't langrange multipliers from linear algebra? D:

bad memories


Err, Lagrangians are generally introduced in calc 3. You're probably thinking of all the times you had to use lambda to calculate eigenvalues and Jordan canonical form and crap.
Moderator
Caller
Profile Blog Joined September 2007
Poland8075 Posts
November 21 2009 06:58 GMT
#7
On November 21 2009 15:16 pangshai wrote:
damn i was hoping this would be more for the interested layman, but its getting a bit too complex for me. good job with the tutorials though, i'm sure others will benefit!

i'm getting back to the layman

hold up
Watch me fail at Paradox: http://www.teamliquid.net/forum/viewmessage.php?topic_id=397564
Carnivorous Sheep
Profile Blog Joined November 2008
Baa?21244 Posts
November 21 2009 07:13 GMT
#8
Lagrangians are kinda everywhere. It's very oppressive, actually, when you start seeing them in every class you take, from physics in the morning to math to econ >.>
TranslatorBaa!
datscilly
Profile Blog Joined November 2007
United States529 Posts
November 21 2009 07:47 GMT
#9
Every part of OP taught me something, and I'm looking forward to the next one.

I have a question though. It's a little long, and here it goes: The overall goal of all this is to solve for x1 and x2 in terms of M, p1, and p2, given M = p1x1 + p2x2, and given that U(x1, x2) = (x1)(x2) is to be maximized. Here x1 and x2 play symmetric roles. + Show Spoiler +
More exactly, if you switch x1 with x2 and switch p1 with p2 at the same time, the equations are unchanged
The answer, X1 = M/(2p2) and X2 = p1M/(2p2^2), is not symmetric.

And I was wondering why symmetry was broken and found that L, the Lagrangian function, was defined asymmetrically: L = U(x1, x2) + λ(M-p1x1 + p2x2). Since M = p1x1 + p2x2, one would expect λ(M-p1x1 - p2x2) instead of λ(M-p1x1 + p2x2).

So my two questions are, why is symmetry broken, which is an iffy question and might not have an answer, and two, why is the Lagrangian function defined the way it is, which should have an answer.
I'm willing to read some links and do some learning myself in order to understand your answer. Wikipedia says in general, to maximize f(x,y), subject to g(x,y) = c, let L = f(x,y) + λ(g(x,y) - c). Actually this would point to λ(M-p1x1 - p2x2), instead of λ(M-p1x1 + p2x2) as you wrote.
Steelflight-Rx
Profile Blog Joined July 2007
United States1389 Posts
November 21 2009 08:10 GMT
#10
yeah man i'm too drunk for this shit, how do i get to that drunk thread..
yubee wrote: you know? it's a great night you should all smile no matter what harddships, because grass grows and the sky is blue and it's a good life.
Scaramanga
Profile Blog Joined March 2008
Australia8092 Posts
November 21 2009 08:32 GMT
#11
Economics maths i was hoping this was theory
Loda talked about the fun counter, it's AdmiralBulldog on his natures prophet
Two_DoWn
Profile Blog Joined October 2009
United States13684 Posts
November 21 2009 08:43 GMT
#12
I come to TL to get away from my econ major, not to be reminded of it. Curse you Caller.
"What is the air speed velocity of an unladen courier?" "Dire or Radiant?"
Caller
Profile Blog Joined September 2007
Poland8075 Posts
Last Edited: 2009-11-21 09:28:38
November 21 2009 09:12 GMT
#13
On November 21 2009 16:47 datscilly wrote:
Every part of OP taught me something, and I'm looking forward to the next one.

I have a question though. It's a little long, and here it goes: The overall goal of all this is to solve for x1 and x2 in terms of M, p1, and p2, given M = p1x1 + p2x2, and given that U(x1, x2) = (x1)(x2) is to be maximized. Here x1 and x2 play symmetric roles. + Show Spoiler +
More exactly, if you switch x1 with x2 and switch p1 with p2 at the same time, the equations are unchanged
The answer, X1 = M/(2p2) and X2 = p1M/(2p2^2), is not symmetric.

And I was wondering why symmetry was broken and found that L, the Lagrangian function, was defined asymmetrically: L = U(x1, x2) + λ(M-p1x1 + p2x2). Since M = p1x1 + p2x2, one would expect λ(M-p1x1 - p2x2) instead of λ(M-p1x1 + p2x2).

So my two questions are, why is symmetry broken, which is an iffy question and might not have an answer, and two, why is the Lagrangian function defined the way it is, which should have an answer.
I'm willing to read some links and do some learning myself in order to understand your answer. Wikipedia says in general, to maximize f(x,y), subject to g(x,y) = c, let L = f(x,y) + λ(g(x,y) - c). Actually this would point to λ(M-p1x1 - p2x2), instead of λ(M-p1x1 + p2x2) as you wrote.


oh whoooooopssssssssssssssss
my bad
thanks for catching that mistake
that'll teach me to half-ass economics
edit: while I did write the wrong thing, the derivatives I took were of the right thing. So the results should still be the same. The reason why symmetry is broken is purely because or the difference between p1 and p2.
It would seem that p1 and p2 would give you the same answer: However, keep in mind that p1 and p2 are different. Let's flip around our results, for instance:
so instead of

p1/p2 = (du/dx1)/(du/dx2)


we now have

p2/p1 = (du/dx2)/(du/dx1)


And using the same equation above, we should get

p2/p1 = x1/x2

which gives us:

x1 = x2p2/p1


If you plug our results in, you see clearly that it forms an identity, confirming our results.
X1 = M/(2p2) and X2 = p1M/(2p2^2).

Also keep in mind that the function itself is not symmetrical-there is an M, for instance, and we cannot split the M up into two parts. As a result, it will be present in both cases, albeit with different contexts.
Because we have these three exogeneous variables, we cannot guarantee that the results will be symmetric. It is possible that these values may be such that our actual numerical answer is symmetric, but it is equally possible that they are not.

There is also one more thing to note about this economic implication:

There is a concept called price effect, which is saying that the amount of stuff you buy changes in response to how the price changes. For instance, usually, when you buy bread, and the price goes down, you may buy more bread. However, there are other possibilities. A Giffin good, for instance, is one where you buy more of it as the price goes up, i.e. that price effect is positive.
There really isn't anything that's a real Giffin good, but one possible example could be toothpaste. Suppose you only do two things with your money: buying toothpaste and going to the dentist. Suppose the price of toothpaste goes up. Now you can't go to the dentist as much. However, because you can't go to the dentist, you need to buy more toothpaste, even though the price went up.
Another possible solution is that you don't change your consumption of the good as the price goes up. For instance, I may use the money I save from bread to hire prostitutes, rather than to buy more bread for my damn kids.

A mathematical version of price effect is, simply, dx1/dp1, or, the change in x1 in response to the change in price. A positive price effect means you buy more x1 in response to an increase in the price of x1. A negative effect means you buy less in response to an increase, etc.

In our case, if we were to calculate the price effect, we would get:

X1 = M/(2p2) and X2 = p1M/(2p2^2).
dx1/dp1 = 0, dx2/dp1 = M/(2p2^2)


This tells us two very interesting things. Firstly, the price effect for x1 is zero. This means that, no matter what the change in price, the person will always buy the same amount of x1. However, for x2, we have a figure. Although it seems tricky, with a little intuition you can figure out the following:
Firstly, M, our budget, has to be positive. This should be obvious.
Secondly, p2, our price, also has to be positive. This should also be obvious because you're not selling bread or prostitutes back.
Therefore, this means that the price effect is positive for x2 in response to x1. That is, if the price in x1 goes up, you buy more x2. This should make sense. If i have to choose between bread and prostitutes, and the price in bread goes down, I hire prostitutes rather than get fat. Similarly, if the price in bread goes up, I hire less prostitutes and buy enough to keep me from starving.

There is also an income effect, which asks whether or not your M value increases or decreases. We quantify that as dx/dM, i.e. how much do you change how much you buy based on how your amount of money changes?

For our case, we could calculate it to be

X1 = M/(2p2) and X2 = p1M/(2p2^2).
dx1/dM = 1/(2p2) and dx2/dM = p1/(2p2^2)

And both of which are positive. This tells us that the more money we have, the more we buy of each stuff. There are cases in which we buy less of something if we have more money, in which case the product is called an inferior good (as opposed to a Giffin good or a normal good). For instance, an inferior good could be ugly prostitutes. The more money I have, the less money I'll spend on ugly prostitutes and the more money I can spend on hot prostitutes.
Watch me fail at Paradox: http://www.teamliquid.net/forum/viewmessage.php?topic_id=397564
imDerek
Profile Blog Joined August 2007
United States1944 Posts
November 21 2009 09:47 GMT
#14
weird i did lagrange multipliers in high school but never did it in college and im in engineering too
Least favorite progamers: Leta, Zero, Mind, Shine, free, really <-- newly added
datscilly
Profile Blog Joined November 2007
United States529 Posts
November 21 2009 10:44 GMT
#15
Hmm, I think I found another mistake, one which means that the solutions are different than up there, and that it's symmetric after all.

On November 21 2009 14:07 Caller wrote:
0 = M – p1x1 - p2(p1x1/p2)

And now we do basic math to get:

2p2x1 = M
X1 = M/(2p2)

It should be
2p1x1 = M
X1 = M/(2p1)

instead. X2 = M/(2p2) will also hold.

The symmetry thing was really bothering me because of the following: if you substitute x1 for x2, x2 for x1, p1 for p2, and p2 for p1, the given equations for the problem, including the equation for U, look exactly the same. Since all the equations after that are logical consequences of the first two equations up top and the equation for U, doing all the substitutions for any equation you get should result in another equation which is true. + Show Spoiler +
One can think of it this way: there are two universes, one where we write down the original equations M = p1x1 + p2x2, L = U(x1, x2) + λ(M-p1x1 + p2x2), U = (x1)(x2), and find consequences of those equations, and another universe where we do those four substitutions on the original equations, and find consequences of those equations. Since the original equations remain unchanged, every logical consequence of the mirror universe is in fact true in the original universe as well.

So X1 = M/(2p2), X2 = p1M/(2p2^2), can't be the solution, since mirroring X1 = M/(2p2) gets us X2 = M/(2p1), and then we have 1 = (p1^2)/(p2^2) after some work, which doesn't make sense.

Right, so I went through all this to talk about a type of reasoning that works for any math problem, and to explain why I looked for a mistake in the first place.
Empyrean
Profile Blog Joined September 2004
17050 Posts
November 22 2009 08:37 GMT
#16
On November 21 2009 18:47 imDerek wrote:
weird i did lagrange multipliers in high school but never did it in college and im in engineering too


You use them a lot in Engineering...especially in optimization problems.

That's kind of strange that you don't use them in your engineering classes.

I assume you took calc 3 in high school? Lagrange multipliers are usually introduced around the time when partial derivatives are introduced, which is fairly early in calc 3.
Moderator
Please log in or register to reply.
Live Events Refresh
WardiTV Winter Champion…
12:00
Playoffs
herO vs Clem
MaxPax vs Cure
WardiTV1386
TKL 346
IndyStarCraft 249
EnkiAlexander 59
IntoTheiNu 15
LiquipediaDiscussion
[ Submit Event ]
Live Streams
Refresh
StarCraft 2
Lowko435
TKL 346
IndyStarCraft 249
Rex 137
LamboSC2 118
BRAT_OK 65
Vindicta 32
EmSc Tv 12
JuggernautJason4
MindelVK 1
StarCraft: Brood War
Britney 25543
Sea 11804
firebathero 591
Rock 28
NaDa 27
Dota 2
Gorgc5392
qojqva1236
monkeys_forever169
BananaSlamJamma51
Counter-Strike
fl0m2636
Super Smash Bros
Mew2King66
Heroes of the Storm
Khaldor457
Liquid`Hasu281
Trikslyr43
Other Games
tarik_tv4753
singsing1437
FrodaN1075
B2W.Neo1069
Mlord410
DeMusliM265
Fuzer 158
KnowMe115
QueenE67
Organizations
Dota 2
PGL Dota 2 - Main Stream9066
PGL Dota 2 - Secondary Stream1494
Other Games
BasetradeTV111
StarCraft 2
EmSc Tv 12
EmSc2Tv 12
Blizzard YouTube
StarCraft: Brood War
BSLTrovo
sctven
[ Show 16 non-featured ]
StarCraft 2
• iHatsuTV 18
• Adnapsc2 9
• LaughNgamezSOOP
• AfreecaTV YouTube
• sooper7s
• intothetv
• Migwel
• Kozan
• IndyKCrew
StarCraft: Brood War
• blackmanpl 31
• STPLYoutube
• ZZZeroYoutube
• BSLYoutube
League of Legends
• Nemesis6386
• TFBlade1120
• Shiphtur177
Upcoming Events
PSISTORM Gaming Misc
7m
AI Arena Tournament
3h 12m
Patches Events
6h 12m
Replay Cast
7h 12m
Sparkling Tuna Cup
17h 12m
RSL Revival
17h 12m
Classic vs TriGGeR
Cure vs Cham
WardiTV Winter Champion…
19h 12m
OSC
19h 42m
BSL
1d 3h
Replay Cast
1d 7h
[ Show More ]
Replay Cast
1d 16h
Monday Night Weeklies
2 days
OSC
2 days
Replay Cast
4 days
The PondCast
4 days
Replay Cast
5 days
Replay Cast
6 days
CranKy Ducklings
6 days
Liquipedia Results

Completed

Proleague 2026-03-05
PiG Sty Festival 7.0
Underdog Cup #3

Ongoing

KCM Race Survival 2026 Season 1
Jeongseon Sooper Cup
Spring Cup 2026
ASL Season 21: Qualifier #1
RSL Revival: Season 4
WardiTV Winter 2026
Nations Cup 2026
ESL Pro League S23 Stage 1&2
PGL Cluj-Napoca 2026
IEM Kraków 2026
BLAST Bounty Winter 2026
BLAST Bounty Winter Qual

Upcoming

ASL Season 21: Qualifier #2
ASL Season 21
Acropolis #4 - TS6
Acropolis #4
IPSL Spring 2026
CSLAN 4
HSC XXIX
uThermal 2v2 2026 Main Event
Bellum Gens Elite Stara Zagora 2026
NationLESS Cup
CS Asia Championships 2026
Asian Champions League 2026
IEM Atlanta 2026
PGL Astana 2026
BLAST Rivals Spring 2026
CCT Season 3 Global Finals
IEM Rio 2026
PGL Bucharest 2026
Stake Ranked Episode 1
BLAST Open Spring 2026
ESL Pro League S23 Finals
TLPD

1. ByuN
2. TY
3. Dark
4. Solar
5. Stats
6. Nerchio
7. sOs
8. soO
9. INnoVation
10. Elazer
1. Rain
2. Flash
3. EffOrt
4. Last
5. Bisu
6. Soulkey
7. Mini
8. Sharp
Sidebar Settings...

Advertising | Privacy Policy | Terms Of Use | Contact Us

Original banner artwork: Jim Warren
The contents of this webpage are copyright © 2026 TLnet. All Rights Reserved.