Skip to content

feat(Analysis/Matrix): add Jacobian matrix for matrix-valued functions#33786

Open
hdmkindom wants to merge 8 commits intoleanprover-community:masterfrom
hdmkindom:gradient
Open

feat(Analysis/Matrix): add Jacobian matrix for matrix-valued functions#33786
hdmkindom wants to merge 8 commits intoleanprover-community:masterfrom
hdmkindom:gradient

Conversation

@hdmkindom
Copy link
Copy Markdown

This PR introduces the Jacobian matrix for matrix-valued functions F : Matrix m n ℝ → Matrix p q ℝ.

The Jacobian matrix jacobianMatrix F X at point X is indexed by (p × q) × (m × n), where each entry represents the partial derivative with respect to a basis element. To handle instance-mismatch issues with matrix norms, we use local Frobenius norm instances.

mkdir Analysis/Matrix/Jacobian.lean

Main definitions

  • jacobianMatrix F X: The Jacobian matrix at point X, defined by jacobianMatrix F X (i, k) (j, l) = (fderiv ℝ F X (Matrix.single j l 1)) i k

Main theorems

  • fderiv_eq_jacobian_mul: Express the Fréchet derivative as a contraction with the Jacobian
  • jacobianMatrix_comp: Chain rule for Jacobian matrices
  • jacobianMatrix_linear, jacobianMatrix_id, jacobianMatrix_const: Basic properties
  • jacobianMatrix_add, jacobianMatrix_smul: Linearity properties

This PR introduces the Jacobian matrix for functions F : Matrix m n ℝ → Matrix p q ℝ.

Main definitions:
- `jacobianMatrix F X`: The Jacobian matrix at point X, indexed by (p × q) × (m × n)

Main theorems:
- `fderiv_eq_jacobian_mul`: Express fderiv in terms of Jacobian entries
- `jacobianMatrix_comp`: Chain rule for Jacobian matrices
- Basic rules: linearity, identity, constant, addition, scalar multiplication
This PR introduces the Jacobian matrix for functions F : Matrix m n ℝ → Matrix p q ℝ.

Main definitions:
- `jacobianMatrix F X`: The Jacobian matrix at point X, indexed by (p × q) × (m × n)

Main theorems:
- `fderiv_eq_jacobian_mul`: Express fderiv in terms of Jacobian entries
- `jacobianMatrix_comp`: Chain rule for Jacobian matrices
- Basic rules: linearity, identity, constant, addition, scalar multiplication
@github-actions github-actions Bot added new-contributor This PR was made by a contributor with at most 5 merged PRs. Welcome to the community! t-analysis Analysis (normed *, calculus) labels Jan 9, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jan 9, 2026

PR summary bd33e8d4d0

Import changes for modified files

No significant changes to the import graph

Import changes for all files
Files Import difference
Mathlib.Analysis.Matrix.Jacobian (new file) 1993

Declarations diff

+ fderiv_eq_jacobian_mul
+ jacobianMatrix
+ jacobianMatrix_add
+ jacobianMatrix_comp
+ jacobianMatrix_const
+ jacobianMatrix_eq_fderiv_basis
+ jacobianMatrix_id
+ jacobianMatrix_linear
+ jacobianMatrix_smul
+ matrix_fderiv_comp

You can run this locally as follows
## summary with just the declaration names:
./scripts/declarations_diff.sh <optional_commit>

## more verbose report:
./scripts/declarations_diff.sh long <optional_commit>

The doc-module for script/declarations_diff.sh contains some details about this script.


No changes to technical debt.

You can run this locally as

./scripts/technical-debt-metrics.sh pr_summary
  • The relative value is the weighted sum of the differences with weight given by the inverse of the current value of the statistic.
  • The absolute value is the relative value divided by the total sum of the inverses of the current values (i.e. the weighted average of the differences).

hdmkindom and others added 6 commits January 9, 2026 13:29
This PR introduces the Jacobian matrix for functions F : Matrix m n ℝ → Matrix p q ℝ.

Main definitions:
- `jacobianMatrix F X`: The Jacobian matrix at point X, indexed by (p × q) × (m × n)

Main theorems:
- `fderiv_eq_jacobian_mul`: Express fderiv in terms of Jacobian entries
- `jacobianMatrix_comp`: Chain rule for Jacobian matrices
- Basic rules: linearity, identity, constant, addition, scalar multiplication
@jcommelin
Copy link
Copy Markdown
Member

mkdir Analysis/Matrix/Jacobian.lean

Please remove this line from the PR description. If you meant to indicate that you are adding a new file, please say that. mkdir is a command to create new directories.

Comment on lines +117 to +119
(F : Matrix m n ℝ → Matrix p q ℝ)
(G : Matrix p q ℝ → Matrix r s ℝ)
(X : Matrix m n ℝ)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you extract these into variable statement as well.

`J[(i, k), (j, l)] = (fderiv ℝ F X (Matrix.single j l 1)) i k`.
-/
noncomputable def jacobianMatrix
(F : Matrix m n ℝ → Matrix p q ℝ) (X : Matrix m n ℝ) :
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you generalize this from to non-trivially normed fields?

@jcommelin jcommelin added the awaiting-author A reviewer has asked the author a question or requested changes. label Feb 17, 2026
@jcommelin jcommelin assigned sgouezel and unassigned ADedecker Feb 17, 2026
noncomputable def jacobianMatrix
(F : Matrix m n ℝ → Matrix p q ℝ) (X : Matrix m n ℝ) :
Matrix (p × q) (m × n) ℝ :=
fun (i, k) (j, l) => (fderiv ℝ F X (Matrix.single j l (1 : ℝ))) i k
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
fun (i, k) (j, l) => (fderiv ℝ F X (Matrix.single j l (1 : ℝ))) i k
fun (i, k) (j, l) => fderiv ℝ F X (Matrix.single j l (1 : ℝ)) i k

Comment on lines +76 to +102
-- unfold Jacobian entries
simp only [jacobianMatrix_eq_fderiv_basis]
-- decompose `H` into the standard basis
have h_decomp : H = ∑ j : m, ∑ l : n, Matrix.single j l (H j l) := by
simpa using (Matrix.matrix_eq_sum_single H)
conv_lhs => rw [h_decomp]
-- linearity through sums
simp only [map_sum]
-- pull out entries `(i, k)`
rw [Finset.sum_apply, Finset.sum_apply]
refine Finset.sum_congr rfl ?_
intro j _
rw [Finset.sum_apply, Finset.sum_apply]
refine Finset.sum_congr rfl ?_
intro l _
-- rewrite `single j l (H j l)` as a scalar multiple of `single j l 1`
have hs : Matrix.single j l (H j l) = (H j l) • Matrix.single j l (1 : ℝ) := by
simp only [smul_single, smul_eq_mul, mul_one]
-- apply `map_smul` and commute the scalar
calc
(fderiv ℝ F X) (Matrix.single j l (H j l)) i k
= (fderiv ℝ F X) ((H j l) • Matrix.single j l (1 : ℝ)) i k := by
rw [hs]
_ = (H j l) * (fderiv ℝ F X) (Matrix.single j l (1 : ℝ)) i k := by
rw [map_smul, smul_apply, smul_eq_mul]
_ = (fderiv ℝ F X) (Matrix.single j l (1 : ℝ)) i k * H j l := by
simp [mul_comm]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think you can try to utilize simp more.

Suggested change
-- unfold Jacobian entries
simp only [jacobianMatrix_eq_fderiv_basis]
-- decompose `H` into the standard basis
have h_decomp : H = ∑ j : m, ∑ l : n, Matrix.single j l (H j l) := by
simpa using (Matrix.matrix_eq_sum_single H)
conv_lhs => rw [h_decomp]
-- linearity through sums
simp only [map_sum]
-- pull out entries `(i, k)`
rw [Finset.sum_apply, Finset.sum_apply]
refine Finset.sum_congr rfl ?_
intro j _
rw [Finset.sum_apply, Finset.sum_apply]
refine Finset.sum_congr rfl ?_
intro l _
-- rewrite `single j l (H j l)` as a scalar multiple of `single j l 1`
have hs : Matrix.single j l (H j l) = (H j l) • Matrix.single j l (1 : ℝ) := by
simp only [smul_single, smul_eq_mul, mul_one]
-- apply `map_smul` and commute the scalar
calc
(fderiv ℝ F X) (Matrix.single j l (H j l)) i k
= (fderiv ℝ F X) ((H j l) • Matrix.single j l (1 : ℝ)) i k := by
rw [hs]
_ = (H j l) * (fderiv ℝ F X) (Matrix.single j l (1 : ℝ)) i k := by
rw [map_smul, smul_apply, smul_eq_mul]
_ = (fderiv ℝ F X) (Matrix.single j l (1 : ℝ)) i k * H j l := by
simp [mul_comm]
-- decompose `H` into the standard basis
have h_decomp : H = ∑ j : m, ∑ l : n, H j l • Matrix.single j l 1 := by
simpa using Matrix.matrix_eq_sum_single H
conv_lhs => rw [h_decomp]
simp [-smul_single, Matrix.sum_apply, mul_comm]

Comment on lines +56 to +62
@[simp]
theorem jacobianMatrix_eq_fderiv_basis
(F : Matrix m n ℝ → Matrix p q ℝ) (X : Matrix m n ℝ)
(i : p) (k : q) (j : m) (l : n) :
jacobianMatrix F X (i, k) (j, l) =
(fderiv ℝ F X) (Matrix.single j l (1 : ℝ)) i k := by
rfl
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
@[simp]
theorem jacobianMatrix_eq_fderiv_basis
(F : Matrix m n ℝ → Matrix p q ℝ) (X : Matrix m n ℝ)
(i : p) (k : q) (j : m) (l : n) :
jacobianMatrix F X (i, k) (j, l) =
(fderiv ℝ F X) (Matrix.single j l (1 : ℝ)) i k := by
rfl
@[simp]
theorem jacobianMatrix_eq_fderiv_basis
(F : Matrix m n ℝ → Matrix p q ℝ) (X : Matrix m n ℝ)
(ik : p × q) (jl : m × n) :
jacobianMatrix F X ik jl = fderiv ℝ F X (Matrix.single jl.1 jl.2 1) ik.1 ik.2 := rfl
  1. The left hand side is syntactically more general when you do not assume it is applied to arguments of the form (i, k) and applies more easily.
  2. rfl as a proof is better than by rfl because the former proof registers the lemma as a dsimp lemma.

Comment on lines +168 to +180
if i = j ∧ k = l then (1 : ℝ) else 0 := by
classical
simp only [jacobianMatrix, fderiv_id, ContinuousLinearMap.coe_id', id_eq]
by_cases h : (i = j ∧ k = l)
· rcases h with ⟨rfl, rfl⟩
simp only [Matrix.single_apply_same]
simp only [and_self, ↓reduceIte]
· have h' : ¬ (j = i ∧ l = k) := by
intro hji
apply h
exact ⟨hji.1.symm, hji.2.symm⟩
simp only [h, Matrix.single_apply_of_ne (i := j) (j := l) (c := (1 : ℝ)) (i' := i) (j' := k) h']
simp only [↓reduceIte]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
if i = j ∧ k = l then (1 : ℝ) else 0 := by
classical
simp only [jacobianMatrix, fderiv_id, ContinuousLinearMap.coe_id', id_eq]
by_cases h : (i = j ∧ k = l)
· rcases h with ⟨rfl, rfl⟩
simp only [Matrix.single_apply_same]
simp only [and_self, ↓reduceIte]
· have h' : ¬ (j = i ∧ l = k) := by
intro hji
apply h
exact ⟨hji.1.symm, hji.2.symm⟩
simp only [h, Matrix.single_apply_of_ne (i := j) (j := l) (c := (1 : ℝ)) (i' := i) (j' := k) h']
simp only [↓reduceIte]
if i = j ∧ k = l then 1 else 0 := by
simp [Matrix.single_apply]
grind

Comment on lines +186 to +188
classical
simp only [jacobianMatrix, fderiv_fun_const, Pi.zero_apply, ContinuousLinearMap.zero_apply,
zero_apply]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
classical
simp only [jacobianMatrix, fderiv_fun_const, Pi.zero_apply, ContinuousLinearMap.zero_apply,
zero_apply]
simp

Comment on lines +195 to +201
jacobianMatrix F X (i, k) (j, l) + jacobianMatrix G X (i, k) (j, l) := by
unfold jacobianMatrix
have h_add : (fun Y => F Y + G Y) = fun Y => (F + G) Y := rfl
rw [h_add]
rw [fderiv_add hF hG]
simp only [ContinuousLinearMap.add_apply]
rfl
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
jacobianMatrix F X (i, k) (j, l) + jacobianMatrix G X (i, k) (j, l) := by
unfold jacobianMatrix
have h_add : (fun Y => F Y + G Y) = fun Y => (F + G) Y := rfl
rw [h_add]
rw [fderiv_add hF hG]
simp only [ContinuousLinearMap.add_apply]
rfl
jacobianMatrix F X (i, k) (j, l) + jacobianMatrix G X (i, k) (j, l) := by
simp [fderiv_fun_add, *]

Comment on lines +209 to +214
unfold jacobianMatrix
have h_smul : (fun Y => c • F Y) = fun Y => (c • F) Y := rfl
rw [h_smul]
rw [fderiv_const_smul hF]
simp only [ContinuousLinearMap.smul_apply]
rfl
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
unfold jacobianMatrix
have h_smul : (fun Y => c • F Y) = fun Y => (c • F) Y := rfl
rw [h_smul]
rw [fderiv_const_smul hF]
simp only [ContinuousLinearMap.smul_apply]
rfl
simp [fderiv_fun_const_smul, *]

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

Labels

awaiting-author A reviewer has asked the author a question or requested changes. new-contributor This PR was made by a contributor with at most 5 merged PRs. Welcome to the community! t-analysis Analysis (normed *, calculus)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants