Skip to content

[Interactive Graph] Add logarithm math utilities to kmath#3421

Open
ivyolamit wants to merge 2 commits intoLEMS-3953/pr1-add-logarithm-type-definitionsfrom
LEMS-3953/pr2-logarithm-kmath
Open

[Interactive Graph] Add logarithm math utilities to kmath#3421
ivyolamit wants to merge 2 commits intoLEMS-3953/pr1-add-logarithm-type-definitionsfrom
LEMS-3953/pr2-logarithm-kmath

Conversation

@ivyolamit
Copy link
Copy Markdown
Contributor

@ivyolamit ivyolamit commented Mar 27, 2026

Summary:

PR series to add logarithm graph support to the Interactive Graph widget:

  1. Add logarithm graph type definitions and data
  2. ▶️ Add logarithm math utilities to kmath
  3. Add logarithm graph state management and reducer
  4. Add logarithm graph rendering, SR strings, and equation string
  5. Add logarithm graph scoring
  6. Add logarithm graph option in the Interactive Graph Editor

Add the logarithm math utilities to kmath for supporting Logarithm graph in Interactive Graph

  • Add LogarithmCoefficient type and getLogarithmCoefficients() to kmath, following the exponential pattern
  • Compute coefficients {a, b, c} for f(x) = a·ln(b·x + c) using the inverse exponential approach
  • No canonical normalization needed (logarithm has no periodic equivalences, same as exponential)

Details

This adds the shared math utility for logarithm coefficient computation to @khanacademy/kmath, following the same pattern as getExponentialCoefficients(). Both the rendering component (PR 4) and scoring (PR 5) will consume this function.

Mathematical approach (inverse exponential):

  1. Flip each coordinate (x, y) → (y, x) — treating the logarithm as the inverse of an exponential
  2. Use the asymptote x-value as the flipped exponential's c coefficient
  3. Compute exponential coefficients aExp, bExp from the flipped points
  4. Invert to get logarithm coefficients: a = 1/bExp, b = 1/aExp, c = -cExp/aExp

Validation guards (returns undefined for invalid inputs):

  • Same y-coordinate on both points (makes bExp undefined)
  • A point lying on the asymptote
  • Points on opposite sides of the asymptote
  • Non-finite or zero intermediate results

This matches the reference implementation in packages/perseus-core/src/utils/grapher-util.ts (the Grapher widget's Logarithm object, lines 449–558).

Co-Authored by Claude Code (Opus)

Issue: LEMS-3953

Test plan

  • pnpm tsc passes
  • pnpm knip passes
  • pnpm lint passes
  • pnpm prettier . --check passes
  • Coefficient tests pass (6 new tests, 17 total in coefficients.test.ts)
  • Grapher test data: [-4,-3], [-5,-7], asymptote -6 reproduces correct y-values
  • Natural log: [1,0], [e,1], asymptote 0a≈1, b≈1, c≈0
  • Negative b: points left of asymptote (y = ln(-x)) → b≈-1
  • Same-y → undefined
  • Point on asymptote → undefined
  • Opposite sides → undefined

…th utilities to kmath for supporting Logarithm graph in Interactive Graph
@ivyolamit ivyolamit self-assigned this Mar 27, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 27, 2026

🗄️ Schema Change: No Changes ✅

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 27, 2026

🛠️ Item Splitting: No Changes ✅

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 27, 2026

Size Change: +134 B (+0.03%)

Total Size: 495 kB

Filename Size Change
packages/kmath/dist/es/index.js 6.35 kB +134 B (+2.16%)
ℹ️ View Unchanged
Filename Size
packages/kas/dist/es/index.js 20.5 kB
packages/keypad-context/dist/es/index.js 1 kB
packages/math-input/dist/es/index.js 98.5 kB
packages/math-input/dist/es/strings.js 1.61 kB
packages/perseus-core/dist/es/index.item-splitting.js 12 kB
packages/perseus-core/dist/es/index.js 25.2 kB
packages/perseus-editor/dist/es/index.js 101 kB
packages/perseus-linter/dist/es/index.js 9.3 kB
packages/perseus-score/dist/es/index.js 9.66 kB
packages/perseus-utils/dist/es/index.js 403 B
packages/perseus/dist/es/index.js 193 kB
packages/perseus/dist/es/strings.js 8.09 kB
packages/pure-markdown/dist/es/index.js 1.39 kB
packages/simple-markdown/dist/es/index.js 6.71 kB

compressed-size-action

@github-actions
Copy link
Copy Markdown
Contributor

npm Snapshot: Published

Good news!! We've packaged up the latest commit from this PR (48b121b) and published it to npm. You
can install it using the tag PR3421.

Example:

pnpm add @khanacademy/perseus@PR3421

If you are working in Khan Academy's frontend, you can run the below command.

./dev/tools/bump_perseus_version.ts -t PR3421

If you are working in Khan Academy's webapp, you can run the below command.

./dev/tools/bump_perseus_version.js -t PR3421

@ivyolamit
Copy link
Copy Markdown
Contributor Author

@claude review

Copy link
Copy Markdown

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — clean, well-tested math utility following the existing exponential pattern.

Extended reasoning...

Overview

Adds LogarithmCoefficient type and getLogarithmCoefficients() to packages/kmath/src/coefficients.ts, exports the type in index.ts, and adds a changeset file. 4 files changed, all additive.

Mathematical correctness

The inverse-exponential derivation is sound. For f(x) = a·ln(b·x + c), flipping coordinates transforms the problem into fitting an exponential x = aExp·e^(bExp·y) + cExp where cExp = asymptote. Inverting gives a = 1/bExp, b = 1/aExp, c = -cExp/aExp — all verified algebraically. The validation guards (same-y, point on asymptote, opposite sides, non-finite/zero intermediates) correctly cover degenerate cases, including the extra bExp === 0 guard needed because a = 1/bExp.

Security risks

None. This is a pure math utility with no I/O or user-input handling.

Level of scrutiny

Low. The change is additive-only, follows an established pattern (getExponentialCoefficients), and all checks passed (tsc, lint, prettier, knip). The 6 new tests exercise both happy paths and all four error/invalid-input cases.

Other factors

No CODEOWNERS concerns for this kmath utility file. Bundle impact is +134 B, as expected.

@ivyolamit ivyolamit marked this pull request as ready for review March 27, 2026 14:46
Copy link
Copy Markdown

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

Copy link
Copy Markdown
Contributor

@SonicScrewdriver SonicScrewdriver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great to me! The graph appears to work well when I manually test as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants