Mass–Energy · The two-ledger derivation

Opposite pulses and two energy ledgers.

If a body at rest emits two equal pulses of light in opposite directions, what do the energy accounting books of two different inertial observers force you to conclude about the body's energy of motion?

An executable model

Two ledgers and opposite pulses

Static worked example

Model note
  • Light complex energy (moving system) (lightComplexEnergyMoving): Host calculation, by the site's own reference code. Computed in massEnergy.movingBalanceLight.
  • Emitted energy (object rest frame) (emittedEnergyRestFrame): Host calculation, by the site's own reference code. Computed in massEnergy.restBalanceLight.
  • Body energy before emission (stationary system) (bodyEnergyRestBefore): Host calculation, by the site's own reference code. Computed in massEnergy.restBodyBefore.
  • Body energy after emission (stationary system) (bodyEnergyRestAfter): Host calculation, by the site's own reference code. Computed in massEnergy.restBodyAfter.
  • Body energy before emission (moving system) (bodyEnergyMovingBefore): Host calculation, by the site's own reference code. Computed in massEnergy.movingBodyBefore.
  • Body energy after emission (moving system) (bodyEnergyMovingAfter): Host calculation, by the site's own reference code. Computed in massEnergy.movingBodyAfter.
  • Body kinetic energy difference (moving system) (kineticEnergyDifference): Host calculation, by the site's own reference code. Computed in massEnergy.kineticEnergyDifference.
  • Additive energy constant (additiveEnergyConstant): Host calculation, by the site's own reference code. Computed in massEnergy.additiveEnergyConstant.
  • Computed from the settings last applied (settings revision 1, result 1).
  • Not modeled: recoil from asymmetric emission; finite pulse duration and shape; the emission mechanism; radiation pressure on the body during emission; gravity; the quantum nature of light; the body's absolute rest energy (kept symbolic).

Predict before the numbers

If the body emits the two opposite pulses at an angle φ = 60° rather than along the direction of motion (φ = 0°), what happens to the total energy of the two light pulses measured by the moving observer?

Three relations the model could have

The result appears when you choose, say you have one in mind, or skip.

Try
Experiment settings emitted energy, the premise, how internal energy is written, notation, a link to these settings
The additive constant C
Internal energies written as
Notation

Worked example: a body emits 1 L of light in its rest frame; seen from a frame moving at 0.6c the two pulses carry 1.25 L together, and the body's kinetic energy falls by 0.25 L.

Seen from a frame moving at v = 0.6c

The body sends out two equal pulses in opposite directions, at φ = 0° to the direction of motion.

v = 0.6cbodypulse 1: 0.25 Lpulse 2: 1 L

The two energy accounts

Each line in units of the emitted energy L, for the accepted settings: v = 0.6c, φ = 0°. The body sends out two equal halves, L/2 each, in its own frame; the moving frame sees them unequal.
Line of the accountRest frame (K₀)Moving frame (k)
Body's energy before emissionE₀H₀
Light sent out1 L1.25 L
…of which pulse 1L/20.25 L
…of which pulse 2L/21 L
…the two pulses togetherL1.25 L
Body's energy after emissionE₁H₁
The account as an equationE₀ − E₁ = L; H₀ − H₁ = 1/√(1 − v²/V²)·L

Subtracting one account from the other

(H₀ − E₀) − (H₁ − E₁) = L(1/√(1 − v²/V²) − 1)

Drop in energy of motion: 0.25 L

The body's internal energies at rest cancel.

Show the code

The site’s own reference code for this law, in TypeScript. It computes the numbers above when the page runs it, and it is what the page uses wherever a FrankenSim result is not available.

evaluatePulseEnergies · src/physics/reference/massEnergy.ts · this site’s source, as built · sha256:eeb7552ef2676c312d9ed38a3601b7b3e1ed2387493ddaf20fd923234c7546de

This function computes the listed outputs when it runs.

In words

Seen from the moving frame, each of the two pulses carries half the emitted energy, times the Lorentz factor, times one minus or one plus the frame speed times the cosine of the emission angle. The angle cancels in the sum, which is the Lorentz factor times the emitted energy.

Implementation

/**
 * Kernel function: evaluates the moving-frame pulse energies and their angle-invariant sum (Paper 4, §1 & Paper 3, §8).
 * Pulse 1: (L/2) * gamma * (1 - beta * cos(phi))
 * Pulse 2: (L/2) * gamma * (1 + beta * cos(phi))
 * Sum: gamma * L
 */
export function evaluatePulseEnergies(
  emittedEnergyRestFrame: number,
  frameSpeed: number,
  emissionAngleRad: number,
): Readonly<{
  lorentzFactor: number;
  pulse1Moving: number;
  pulse2Moving: number;
  pulseSumMoving: number;
  pulseEnergyRatio: number;
  dopplerFrequencyRatio: number;
}> {
  const g = 1 / Math.sqrt(1 - frameSpeed * frameSpeed);
  const halfL = emittedEnergyRestFrame / 2;
  const cosPhi = Math.cos(emissionAngleRad);
  const factor1 = 1 - frameSpeed * cosPhi;
  const factor2 = 1 + frameSpeed * cosPhi;
  const p1 = halfL * g * factor1;
  const p2 = halfL * g * factor2;
  const sum = g * emittedEnergyRestFrame;
  const ratio = factor1 / factor2;
  return Object.freeze({
    lorentzFactor: g,
    pulse1Moving: p1,
    pulse2Moving: p2,
    pulseSumMoving: sum,
    pulseEnergyRatio: ratio,
    dopplerFrequencyRatio: ratio,
  });
}

The site’s own reference code for this law, in TypeScript. It computes the numbers above when the page runs it, and it is what the page uses wherever a FrankenSim result is not available.

evaluateLedgers · src/physics/reference/massEnergy.ts · this site’s source, as built · sha256:ad34802170ca8f200c091d17119d686c02b7a4beaf02d073f1722ac74965eae4

This function computes the listed outputs when it runs.

In words

In the frame where the body rests, it loses exactly the energy it emits. In the moving frame it loses the Lorentz factor times that energy. The function returns both balances, and if it is given an initial body energy it first seeds the ledger with it.

Implementation

/**
 * Kernel function: evaluates the rest-frame and moving-frame energy balances (Paper 4, §1).
 * Rest frame balance: E0 - E1 = L
 * Moving frame balance: H0 - H1 = gamma * L
 */
export function evaluateLedgers(
  emittedEnergyRestFrame: number,
  frameSpeed: number,
  _emissionAngleRad: number,
  initialBodyEnergy?: MassEnergyLedgerSeed,
): Readonly<{
  restBalanceLight: number;
  movingBalanceLight: number;
  lorentzFactor: number;
}> {
  if (initialBodyEnergy !== undefined) {
    initializeMassEnergyLedger({ restEnergyBefore: initialBodyEnergy });
  }
  const g = 1 / Math.sqrt(1 - frameSpeed * frameSpeed);
  return Object.freeze({
    restBalanceLight: emittedEnergyRestFrame,
    movingBalanceLight: g * emittedEnergyRestFrame,
    lorentzFactor: g,
  });
}

The site’s own reference code for this law, in TypeScript. It computes the numbers above when the page runs it, and it is what the page uses wherever a FrankenSim result is not available.

evaluateSubtraction · src/physics/reference/massEnergy.ts · this site’s source, as built · sha256:98436f159f767fc6824c6c3c79b8716f767c1e762857e1836ecef2058d24f207

This function computes the listed outputs when it runs.

In words

Subtract the rest-frame balance from the moving-frame balance: the emitted energy times the Lorentz factor minus one. If the premise holds that the additive constant does not change during the emission, that difference is the drop in the body's kinetic energy; with the premise set aside, no kinetic difference is returned. The Lorentz factor minus one is computed so that it does not round to zero at walking speeds, and an observer speed that is not finite and below the speed of light is refused.

Implementation

/**
 * Kernel function: evaluates the subtraction move (H0 - E0) - (H1 - E1) and the resulting kinetic energy difference (Paper 4, §1).
 * Subtraction: (H0 - E0) - (H1 - E1) = L * (gamma - 1)
 * If premise === "unchanged": K0 - K1 = L * (gamma - 1)
 */
export function evaluateSubtraction(
  emittedEnergyRestFrame: number,
  frameSpeed: number,
  _emissionAngleRad: number,
  premise: Me01Premise = "unchanged",
): Readonly<{
  subtractionValue: number;
  lorentzFactor: number;
  kineticDifference: number | null;
  premise: Me01Premise;
}> {
  const g = 1 / Math.sqrt(1 - frameSpeed * frameSpeed);
  // Reuse the cancellation-free owner: gamma - 1 rounds to zero at walking speeds.
  const difference = gammaMinusOne(frameSpeed);
  if (difference.status !== "value") {
    throw new RangeError("Subtraction requires a finite subluminal observer speed.");
  }
  const sub = emittedEnergyRestFrame * difference.value;
  return Object.freeze({
    subtractionValue: sub,
    lorentzFactor: g,
    kineticDifference: premise === "unchanged" ? sub : null,
    premise,
  });
}

The site’s own reference code for this law, in TypeScript. It computes the numbers above when the page runs it, and it is what the page uses wherever a FrankenSim result is not available.

initializeMassEnergyLedger · src/physics/reference/massEnergy.ts · this site’s source, as built · sha256:35f202a64ce0a1738e335423433623920b3e1c01fb8fa0707355cfd4779cbd0d

This function computes the listed outputs when it runs.

In words

Before and after the emission, in each of the two frames, the body has an energy nobody has measured. This function names all four of them, E0 and E1 in the rest frame and H0 and H1 in the moving frame, and returns each as a symbol rather than a value. Naming them is what lets the subtraction remove them.

Implementation

/**
 * Validates and initializes the mass-energy ledger.
 *
 * Enforces the non-circularity doctrine (Paper 4 / AGENTS.md):
 * The mass-energy ledger must NEVER initialise a body's energy with Mc^2 or gamma Mc^2.
 * Rest energy and moving body energy on the historical route must remain symbolic (E₀, H₀).
 * Any attempt to seed the ledger with Mc^2 or gamma Mc^2 is rejected with an Error.
 */
export function initializeMassEnergyLedger(
  seed?: MassEnergyLedgerInit,
): InitializedMassEnergyLedger {
  const isNumericValue = (val: unknown): boolean => {
    if (val === undefined || val === null) return false;
    if (typeof val === "number" && Number.isFinite(val)) return true;
    if (typeof val === "string") {
      const trimmed = val.trim();
      if (trimmed !== "" && !Number.isNaN(Number(trimmed))) return true;
    }
    if (typeof val === "object") {
      const rec = val as Record<string, unknown>;
      if (typeof rec.value === "number" && Number.isFinite(rec.value)) return true;
      if (rec.kind === "numeric" || rec.kind === "value") return true;
      if (typeof rec.numericFrom === "string") return true;
    }
    return false;
  };

  const isCircular = (val: unknown): boolean => {
    if (val === undefined || val === null) return false;
    if (typeof val === "string") {
      const lower = val.toLowerCase().replace(/[\s_*^·×-]/g, "");
      if (
        lower.includes("mc2") ||
        lower.includes("mc²") ||
        lower.includes("gammamc") ||
        lower.includes("γmc") ||
        lower.includes("mc^2")
      ) {
        return true;
      }
    }
    if (typeof val === "object") {
      const rec = val as Record<string, unknown>;
      if (rec.numericFrom === "mc2" || rec.numericFrom === "gamma-mc2") return true;
      if (typeof rec.formula === "string" && isCircular(rec.formula)) return true;
      if (typeof rec.id === "string" && isCircular(rec.id)) return true;
      if (typeof rec.kind === "string" && isCircular(rec.kind)) return true;
      if (typeof rec.expr === "string" && isCircular(rec.expr)) return true;
    }
    return false;
  };

  if (isCircular(seed?.restEnergyBefore) || isCircular(seed?.movingEnergyBefore)) {
    throw new MassEnergyError(
      "absolute-energy-not-admitted",
      "Circularity violation: the mass-energy ledger must NEVER initialise a body's energy with Mc^2 or gamma Mc^2.",
    );
  }

  if (seed?.historicalMode !== false) {
    if (isNumericValue(seed?.restEnergyBefore) || isNumericValue(seed?.movingEnergyBefore)) {
      throw new MassEnergyError(
        "absolute-energy-not-admitted",
        "Supplying a numeric absolute rest energy in the historical model is rejected. Rest and moving energies must remain symbolic.",
      );
    }
  }

  return Object.freeze({
    restBodyBefore: asSymbolic(
      "bodyEnergyRestBefore",
      "J",
      "rest-body-energy-before",
      "massEnergy.restBodyBefore",
      "E₀",
    ),
    restBodyAfter: asSymbolic(
      "bodyEnergyRestAfter",
      "J",
      "rest-body-energy-after",
      "massEnergy.restBodyAfter",
      "E₁",
    ),
    movingBodyBefore: asSymbolic(
      "bodyEnergyMovingBefore",
      "J",
      "moving-body-energy-before",
      "massEnergy.movingBodyBefore",
      "H₀",
    ),
    movingBodyAfter: asSymbolic(
      "bodyEnergyMovingAfter",
      "J",
      "moving-body-energy-after",
      "massEnergy.movingBodyAfter",
      "H₁",
    ),
  });
}

Not modeled in this ideal reference calculation:

recoil from asymmetric emission · finite pulse duration and shape · the emission mechanism · radiation pressure on the body during emission · gravity · the quantum nature of light · the body's absolute rest energy (kept symbolic)

Two equal flashes of light leave a body at rest in opposite directions. Seen by someone moving past, the flashes carry more energy than they do for the body, and the extra can only come from the body's energy of motion, which falls as if the body had lost mass.

The mass–energy paper imports one result from §8 of the relativity paper: light of energy l, seen from a frame moving at v along x, has energy l* = l(1 − (v/V) cos φ)/√(1 − (v/V)²), where φ is the angle between the light's direction and the x-axis. A body at rest in (x, y, z) sends out light of energy L/2 at the angle φ and an equal amount the opposite way, and stays at rest. The energy principle must hold in both frames: in the rest frame E₀ − E₁ = L, and in the moving one H₀ − H₁ = γL, writing γ for 1/√(1 − (v/V)²), because the two direction factors, 1 − (v/V) cos φ and 1 + (v/V) cos φ, add to 2. The body's energies E and H stay symbolic, and the lab never gives them values. Subtracting the two balances removes them: (H₀ − E₀) − (H₁ − E₁) = L{1/√(1 − (v/V)²) − 1}. Each H − E is the body's kinetic energy K in the moving frame plus a constant C, and C does not change during the emission, so K₀ − K₁ = L{1/√(1 − (v/V)²) − 1}. At the lab's default, L = 1 J and v = 0.6c, the moving observer counts 1.25 J of light, and the body's kinetic energy falls by 0.25 J whatever the angle. Drop the premise that C is unchanged and the difference is underdetermined, and the lab says so. To lowest order the drop is (L/V²)(v²/2), the kinetic energy of a mass L/V², and the paper concludes that a body giving off energy L as radiation loses mass L/V².

Modern qualifications

The paper, received on 27 September 1905, writes the factor in full as 1/√(1 − v²/V²), V for the speed of light, L for the emitted energy and l* for the transformed light energy. It cites §8 of the June paper for that transformation and notes in a footnote that the constancy of the speed of light used there is contained in Maxwell's equations. It states the result as L/V², and in cgs units as a mass change of L/9 · 1020 grams for L ergs, and suggests that radium salts might test it. The mass statement rests on the lowest-order term in v/V and on the source premise that C is unchanged. Planck gave a more general treatment in 1907, and Ives argued in 1952 that the 1905 argument was circular, a reading others have disputed. The paper itself says only that the mass of a body is a measure of its energy content.

Open the derivation

The imported light-energy transformation

Einstein imports a result proven in §8 of his third 1905 paper (Special Relativity). When light of energy l is emitted in the stationary system at an angle φ to the direction of relative motion, an observer moving past at speed v measures its energy l* as:

l∗=l1−vVcos⁡φ1−(vV)2l^* = l \frac{1 - \frac{v}{V}\cos\varphi}{\sqrt{1 - \left(\frac{v}{V}\right)^2}}
Explain this equation

In modern notation with β = v/c and the Lorentz factor γ = 1/√(1 − β²):

l∗=l γ (1−βcos⁡φ)l^* = l\,\gamma\,(1 - \beta\cos\varphi)

The two accounting sheets: rest frame and moving frame

Let the body at rest have initial internal energy E₀. It emits two equal light pulses of energy L/2 in opposite directions (φ and φ + 180°). Conservation of energy in the stationary frame requires:

E0=E1+12L+12L=E1+L  ⟹  E0−E1=L\begin{gathered}E_0 = E_1 + \frac{1}{2}L + \frac{1}{2}L = E_1 + L \\ \implies E_0 - E_1 = L\end{gathered}
Explain this equation

Now consider the same physical event as measured by an observer moving at speed v. The initial energy of the body in this frame is H₀. The two pulses have energies:

Pulse 1=12L γ (1−βcos⁡φ),Pulse 2=12L γ (1+βcos⁡φ)\begin{gathered}\text{Pulse 1} = \frac{1}{2}L\,\gamma\,(1 - \beta\cos\varphi), \\ \text{Pulse 2} = \frac{1}{2}L\,\gamma\,(1 + \beta\cos\varphi)\end{gathered}
Explain this equation

When the two pulse energies are added together, the angle terms −β cos φ and +β cos φ cancel identically:

Total moving light=12L γ (1−βcos⁡φ)+12L γ (1+βcos⁡φ)=γL\begin{aligned}&\text{Total moving light} \\ &\quad = \frac{1}{2}L\,\gamma\,(1 - \beta\cos\varphi) \\ &\qquad + \frac{1}{2}L\,\gamma\,(1 + \beta\cos\varphi) \\ &\quad = \gamma L\end{aligned}

Energy conservation in the moving frame therefore gives:

H0=H1+γL  ⟹  H0−H1=γL\begin{gathered}H_0 = H_1 + \gamma L \\ \implies H_0 - H_1 = \gamma L\end{gathered}
Explain this equation

The subtraction: removing the unknown internal energies

Neither E₀ nor H₀ is known. But subtracting the stationary-system balance from the moving-system balance completely eliminates the body's unknown internal rest energy:

(H0−E0)−(H1−E1)=γL−L=L (γ−1)\begin{aligned}&(H_0 - E_0) - (H_1 - E_1) \\ &\qquad = \gamma L - L \\ &\qquad = L\,(\gamma - 1)\end{aligned}
Explain this equation

Identifying the kinetic energy drop

The difference between a body's energy in a moving system and its energy in the rest system differs from its kinetic energy K only by an additive constant C:

H−E=K+CH - E = K + C
Explain this equation

Under Einstein's source premise that the constant C does not alter upon the emission of light (C = C'), substituting this relation yields:

(K0+C)−(K1+C)=K0−K1=L (γ−1)\begin{aligned}(K_0 + C) - (K_1 + C) &= K_0 - K_1 \\ &= L\,(\gamma - 1)\end{aligned}
Explain this equation

The body's energy of motion drops by L(γ − 1) while its speed remains unchanged.

Embed this laboratory on another page. It starts from its worked defaults, not your current settings.