Theil index calculator
Four unequal incomes totalling 100, with a mean of 25, give a Theil index that is positive but far below its ceiling for four people: inequality exists, yet it is moderate. Add group labels to see where it lives. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Incomes
- 10, 20, 30, 40
- N
- 4
- Mean income
- 25
- Total income
- 100
- Theil t
- 0.1064401353
The Theil T index is an entropy-based measure of inequality that turns a list of individual incomes into a single non-negative number: zero when everyone earns the same amount, and larger as income concentrates among fewer people. Economists, policy analysts, and data journalists use it because it is additively decomposable into within-group and between-group components—something the Gini coefficient does not offer cleanly. This capability accepts a distribution of strictly positive incomes, computes the classic Theil T formula with the natural logarithm, reports mean and total income, a theoretical upper bound ln(n), and an optional normalized ratio T/ln(n). When you also supply subgroup labels of the same length, it returns per-group Theil values plus the within and between contributions that sum back to the overall index.
What the Theil T index measures and why entropy matters
Theil T belongs to the generalized-entropy family of inequality measures. When every income equals the mean, each ratio is one, every log term is zero, and T is exactly zero—perfect equality. When one person holds almost all income and others hold tiny positive amounts, the weighted log terms grow and T approaches its finite-sample ceiling of ln(n).
Interpreting T as a Kullback–Leibler divergence between the actual income distribution and the equal-share benchmark is not marketing language: it is the standard information-theoretic reading that justifies the entropy label. Unlike the Gini coefficient, which summarizes the Lorenz curve with a double-counting of pairwise gaps, Theil T is more sensitive to changes at the top of the distribution and admits an exact additive split across population partitions.
That split is why regional accounts, industry wage studies, and school-district funding analyses often prefer Theil when the research question is how much inequality lives inside groups versus how much comes from gaps between groups. This calculator implements that definition with finite-number arithmetic only: no sampling, no model calls, and no hidden reweighting unless you provide the incomes you intend to measure.
Where researchers and analysts use the Theil index
Development economists and national statistical offices compute Theil T on household survey microdata to track inequality trends and to attribute change to within-region versus between-region forces. Corporate compensation teams and HR analytics platforms apply the same formula to salary bands by department or site when they need a decomposable inequality dashboard rather than a single opaque Gini. Keep incomes strictly positive, align optional group labels by index, and you get reproducible entropy-based inequality measures for notebooks, LMS plugins, and edge workers without standing up a statistics stack of your own.
What you can do with it
Survey microdata and regional decomposition
Compute Theil T on household incomes and, with region labels, split inequality into within-region and between-region shares for policy briefs.
Compensation and workforce analytics
Measure pay inequality across employees and decompose by department or site using the same within and between Theil contributions.
Teaching and automated grading
Let students check textbook Theil examples and optional subgroup identities against a deterministic oracle in LMS plugins.
FAQ
Why must every income be strictly positive?
Theil T uses the natural log of income ratios.
How does Theil T differ from the Gini coefficient?
Gini summarizes the Lorenz curve and is not additively decomposable across groups in a simple way. Theil T is entropy-based, more top-sensitive, and splits cleanly into within-group and between-group inequality.
What does a Theil index of zero mean?
Perfect equality: everyone earns the mean, so every log term is zero. The index grows as income concentrates in fewer hands, up to a ceiling equal to the natural log of the number of people.
Can I split inequality between and within groups?
Yes. Add a group label for each income, such as a region or a department. You get each group's own index plus the within-group and between-group parts, which add back up to the overall figure.
What is the normalized Theil index?
It is the index divided by its maximum possible value for that number of people, the natural log of n. That places results for populations of different sizes on a common scale from 0 to 1.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/econ/theil-index-distribution \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"incomes":[10,20,30,40]}'const res = await fetch("https://api.kit.forhosting.com/econ/theil-index-distribution", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"incomes": [
10,
20,
30,
40
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/econ/theil-index-distribution",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"incomes": [
10,
20,
30,
40
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/econ/theil-index-distribution", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"incomes":[10,20,30,40]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"incomes":[10,20,30,40]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/econ/theil-index-distribution", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"incomes": [
10,
20,
30,
40
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "econ.theil_index_distribution",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
What the Theil T index measures and why entropy matters
For a population of n people with strictly positive incomes y_i and arithmetic mean μ, the index is the average of income shares times the log of those shares: T equals one over n times the sum over i of (y_i over μ) times the natural log of (y_i over μ).
Input contract, optional groups, response fields, and errors
Numbers are rounded to twelve decimal places for stable cross-runtime goldens. POST a JSON body with the required field incomes: a non-empty array of strictly positive finite numbers (aliases values, y, and data are accepted). Empty lists, zeros, negatives, and non-finite values fail with invalid_input because the logarithm of a non-positive income ratio is undefined. Optionally send groups (aliases subgroup, labels, region): an array of non-empty labels with the same length as incomes. When groups are present, the solver buckets observations by label, computes each group's own Theil T, then forms within-group inequality as the income-share-weighted sum of those group indices and between-group inequality as the sum of s_g times ln(s_g over p_g), where s_g is the group's share of total income and p_g is its population share. The response always echoes n, mean_income, total_income, theil_t, max_theil as ln(n) for n greater than one (zero for a singleton), normalized_theil as theil_t divided by max_theil when that bound is positive, an equal_share boolean, a formula string, and a short interpretation. With groups it also returns within_theil, between_theil, decomposition_check (their sum, for audit), group_count, and a groups array sorted by label with per-group means, shares, and contributions. Validation failures are not billed; successful calls use the published $0.002 base price per item on the API path while the browser tool remains free.
Where a Theil index API earns its keep in research and product work
Classroom and MOOC platforms use the endpoint as an oracle: students submit small example vectors such as ten-twenty-thirty-forty and verify both the overall T and, when they attach region labels, the within-plus-between identity.
Technical questions
How is the Theil T index calculated from incomes?
For n positive incomes with mean μ, T = (1/n) · Σ (y_i/μ) · ln(y_i/μ). The API returns that value as theil_t, plus mean, total, max_theil = ln(n), and optional normalized_theil = T/ln(n).
How does subgroup decomposition work?
Provide a groups array aligned with incomes. The response includes within_theil, between_theil, and per-group details. By construction, within_theil + between_theil equals the overall theil_t (up to rounding).
What does the Theil index calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.