specular-differentiation 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- specular_differentiation-0.0.1/LICENSE +21 -0
- specular_differentiation-0.0.1/PKG-INFO +114 -0
- specular_differentiation-0.0.1/README.md +91 -0
- specular_differentiation-0.0.1/setup.cfg +4 -0
- specular_differentiation-0.0.1/setup.py +22 -0
- specular_differentiation-0.0.1/specular_diff/__init__.py +0 -0
- specular_differentiation-0.0.1/specular_diff/specular_derivative.py +273 -0
- specular_differentiation-0.0.1/specular_differentiation.egg-info/PKG-INFO +114 -0
- specular_differentiation-0.0.1/specular_differentiation.egg-info/SOURCES.txt +9 -0
- specular_differentiation-0.0.1/specular_differentiation.egg-info/dependency_links.txt +1 -0
- specular_differentiation-0.0.1/specular_differentiation.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 정기엽, Kiyuob Jung
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: specular-differentiation
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Specular differentiation in normed vector spaces and its applications
|
|
5
|
+
Home-page: https://github.com/kyjung2357/specular-differentiation
|
|
6
|
+
Author: Kiyuob Jung
|
|
7
|
+
Author-email: kyjung@msu.edu
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.6
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: author-email
|
|
16
|
+
Dynamic: classifier
|
|
17
|
+
Dynamic: description
|
|
18
|
+
Dynamic: description-content-type
|
|
19
|
+
Dynamic: home-page
|
|
20
|
+
Dynamic: license-file
|
|
21
|
+
Dynamic: requires-python
|
|
22
|
+
Dynamic: summary
|
|
23
|
+
|
|
24
|
+
# Specular Differentiation
|
|
25
|
+
|
|
26
|
+

|
|
27
|
+

|
|
28
|
+
|
|
29
|
+
This repository contains the Python package `specular_diff` and codes for applications:
|
|
30
|
+
|
|
31
|
+
* [**Nonsmooth convex optimization**](#nonsmooth-convex-optimization)
|
|
32
|
+
* Directory: `nonsmooth-convex-opt/`
|
|
33
|
+
* Related reference: [[2]](#references), [[5]](#references)
|
|
34
|
+
|
|
35
|
+
* [**Initial value problems for ordinary differential equations**](#initial-value-problems-for-ordinary-differential-equations)
|
|
36
|
+
* Directory: `numerical-ODE/`
|
|
37
|
+
* Related reference: [[1]](#references), [[3]](#references), [[4]](#references)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
You can install the released version directly from PyPI:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install specular-differentiation
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Introduction
|
|
49
|
+
|
|
50
|
+
*Specular differentiation* generalizes classical differentiation.
|
|
51
|
+
A specular derivative can be understood as the average of the inclination angles of the right and left derivatives.
|
|
52
|
+
In contrast, a symmetric derivative is the average of the right and left derivatives.
|
|
53
|
+
Their difference is illustrated as in the following figure.
|
|
54
|
+
|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
## Applications
|
|
59
|
+
|
|
60
|
+
Specular differentiation is defined in normed vector spaces, allowing for applications in higher-dimensional Euclidean spaces.
|
|
61
|
+
Two applications are provided in this repository.
|
|
62
|
+
|
|
63
|
+
### Nonsmooth convex optimization
|
|
64
|
+
|
|
65
|
+
In [[2]](#references), *the specular gradient method* is introduced for optimizing nonsmooth convex objective functions.
|
|
66
|
+
|
|
67
|
+
### Initial value problems for ordinary differential equations
|
|
68
|
+
|
|
69
|
+
In [[1]](#references), *the specular Euler scheme of Type 5* is introduced for solving ODEs numerically, yielding more accurate numerical solutions than classical schemes: the explicit and implicit Euler schemes and the Crank-Nicolson scheme.
|
|
70
|
+
|
|
71
|
+

|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
## LaTeX notation
|
|
75
|
+
|
|
76
|
+
To use the specular differentiation symbol in your LaTeX document, please refer to the following instructions.
|
|
77
|
+
|
|
78
|
+
### Setup
|
|
79
|
+
|
|
80
|
+
Add the following code to your LaTeX preamble (before `\begin{document}`):
|
|
81
|
+
|
|
82
|
+
```latex
|
|
83
|
+
% Required packages
|
|
84
|
+
\usepackage{graphicx}
|
|
85
|
+
\usepackage{bm}
|
|
86
|
+
|
|
87
|
+
% Definition of Specular Differentiation symbol
|
|
88
|
+
\newcommand\spd[1][.5]{\mathbin{\vcenter{\hbox{\scalebox{#1}{\,$\bm{\wedge}$}}}}}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Usage examples
|
|
92
|
+
|
|
93
|
+
Use the symbol in your document (after `\begin{document}`):
|
|
94
|
+
|
|
95
|
+
```latex
|
|
96
|
+
% A specular derivative in the one-dimensional Euclidean space
|
|
97
|
+
$f^{\spd}(x)$
|
|
98
|
+
|
|
99
|
+
% A specular directional derivative in normed vector spaces
|
|
100
|
+
$\partial^{\spd}_v f(x)$
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
## References
|
|
105
|
+
|
|
106
|
+
[1] K. Jung. *Nonlinear numerical schemes using specular differentiation for initial value problems of first-order ordinary differential equations*. arXiv preprint arXiv:??, 2025.
|
|
107
|
+
|
|
108
|
+
[2] K. Jung. *Specular differentiation in normed vector spaces and its applications to nonsmooth convex optimization*. arXiv preprint arXiv:??, 2025.
|
|
109
|
+
|
|
110
|
+
[3] K. Jung and J. Oh. [*The specular derivative*](https://arxiv.org/abs/2210.06062). *arXiv preprint arXiv:2210.06062*, 2022.
|
|
111
|
+
|
|
112
|
+
[4] K. Jung and J. Oh. [*The wave equation with specular derivatives*](https://arxiv.org/abs/2210.06933). *arXiv preprint arXiv:2210.06933*, 2022.
|
|
113
|
+
|
|
114
|
+
[5] K. Jung and J. Oh. [*Nonsmooth convex optimization using the specular gradient method with root-linear convergence*](https://arxiv.org/abs/2412.20747). *arXiv preprint arXiv:2210.06933*, 2024.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Specular Differentiation
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
|
|
6
|
+
This repository contains the Python package `specular_diff` and codes for applications:
|
|
7
|
+
|
|
8
|
+
* [**Nonsmooth convex optimization**](#nonsmooth-convex-optimization)
|
|
9
|
+
* Directory: `nonsmooth-convex-opt/`
|
|
10
|
+
* Related reference: [[2]](#references), [[5]](#references)
|
|
11
|
+
|
|
12
|
+
* [**Initial value problems for ordinary differential equations**](#initial-value-problems-for-ordinary-differential-equations)
|
|
13
|
+
* Directory: `numerical-ODE/`
|
|
14
|
+
* Related reference: [[1]](#references), [[3]](#references), [[4]](#references)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
You can install the released version directly from PyPI:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install specular-differentiation
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Introduction
|
|
26
|
+
|
|
27
|
+
*Specular differentiation* generalizes classical differentiation.
|
|
28
|
+
A specular derivative can be understood as the average of the inclination angles of the right and left derivatives.
|
|
29
|
+
In contrast, a symmetric derivative is the average of the right and left derivatives.
|
|
30
|
+
Their difference is illustrated as in the following figure.
|
|
31
|
+
|
|
32
|
+

|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
## Applications
|
|
36
|
+
|
|
37
|
+
Specular differentiation is defined in normed vector spaces, allowing for applications in higher-dimensional Euclidean spaces.
|
|
38
|
+
Two applications are provided in this repository.
|
|
39
|
+
|
|
40
|
+
### Nonsmooth convex optimization
|
|
41
|
+
|
|
42
|
+
In [[2]](#references), *the specular gradient method* is introduced for optimizing nonsmooth convex objective functions.
|
|
43
|
+
|
|
44
|
+
### Initial value problems for ordinary differential equations
|
|
45
|
+
|
|
46
|
+
In [[1]](#references), *the specular Euler scheme of Type 5* is introduced for solving ODEs numerically, yielding more accurate numerical solutions than classical schemes: the explicit and implicit Euler schemes and the Crank-Nicolson scheme.
|
|
47
|
+
|
|
48
|
+

|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
## LaTeX notation
|
|
52
|
+
|
|
53
|
+
To use the specular differentiation symbol in your LaTeX document, please refer to the following instructions.
|
|
54
|
+
|
|
55
|
+
### Setup
|
|
56
|
+
|
|
57
|
+
Add the following code to your LaTeX preamble (before `\begin{document}`):
|
|
58
|
+
|
|
59
|
+
```latex
|
|
60
|
+
% Required packages
|
|
61
|
+
\usepackage{graphicx}
|
|
62
|
+
\usepackage{bm}
|
|
63
|
+
|
|
64
|
+
% Definition of Specular Differentiation symbol
|
|
65
|
+
\newcommand\spd[1][.5]{\mathbin{\vcenter{\hbox{\scalebox{#1}{\,$\bm{\wedge}$}}}}}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Usage examples
|
|
69
|
+
|
|
70
|
+
Use the symbol in your document (after `\begin{document}`):
|
|
71
|
+
|
|
72
|
+
```latex
|
|
73
|
+
% A specular derivative in the one-dimensional Euclidean space
|
|
74
|
+
$f^{\spd}(x)$
|
|
75
|
+
|
|
76
|
+
% A specular directional derivative in normed vector spaces
|
|
77
|
+
$\partial^{\spd}_v f(x)$
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
## References
|
|
82
|
+
|
|
83
|
+
[1] K. Jung. *Nonlinear numerical schemes using specular differentiation for initial value problems of first-order ordinary differential equations*. arXiv preprint arXiv:??, 2025.
|
|
84
|
+
|
|
85
|
+
[2] K. Jung. *Specular differentiation in normed vector spaces and its applications to nonsmooth convex optimization*. arXiv preprint arXiv:??, 2025.
|
|
86
|
+
|
|
87
|
+
[3] K. Jung and J. Oh. [*The specular derivative*](https://arxiv.org/abs/2210.06062). *arXiv preprint arXiv:2210.06062*, 2022.
|
|
88
|
+
|
|
89
|
+
[4] K. Jung and J. Oh. [*The wave equation with specular derivatives*](https://arxiv.org/abs/2210.06933). *arXiv preprint arXiv:2210.06933*, 2022.
|
|
90
|
+
|
|
91
|
+
[5] K. Jung and J. Oh. [*Nonsmooth convex optimization using the specular gradient method with root-linear convergence*](https://arxiv.org/abs/2412.20747). *arXiv preprint arXiv:2210.06933*, 2024.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
with open("README.md", "r", encoding="utf-8") as fh:
|
|
4
|
+
long_description = fh.read()
|
|
5
|
+
|
|
6
|
+
setup(
|
|
7
|
+
name="specular-differentiation",
|
|
8
|
+
version="0.0.1",
|
|
9
|
+
author="Kiyuob Jung",
|
|
10
|
+
author_email="kyjung@msu.edu",
|
|
11
|
+
description="Specular differentiation in normed vector spaces and its applications",
|
|
12
|
+
long_description=long_description,
|
|
13
|
+
long_description_content_type="text/markdown",
|
|
14
|
+
url="https://github.com/kyjung2357/specular-differentiation",
|
|
15
|
+
packages=find_packages(),
|
|
16
|
+
classifiers=[
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
],
|
|
21
|
+
python_requires='>=3.6',
|
|
22
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"""
|
|
2
|
+
==================================================
|
|
3
|
+
Calculations of specularly directional derivatives
|
|
4
|
+
==================================================
|
|
5
|
+
|
|
6
|
+
This module provides implementations of the calculations of specularly directional derivatives.
|
|
7
|
+
|
|
8
|
+
==========================
|
|
9
|
+
__author__ = "Kiyuob Jung"
|
|
10
|
+
__version__ = "1.1.0"
|
|
11
|
+
__license__ = "MIT"
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
from typing import Callable, Union
|
|
16
|
+
import numpy as np
|
|
17
|
+
|
|
18
|
+
def safe_to_float(x):
|
|
19
|
+
if isinstance(x, complex):
|
|
20
|
+
if np.isclose(x.imag, 0):
|
|
21
|
+
return float(x.real)
|
|
22
|
+
else:
|
|
23
|
+
raise ValueError(f"Complex value with non-zero imaginary part: {x}")
|
|
24
|
+
return float(x)
|
|
25
|
+
|
|
26
|
+
def A(alpha: float, beta: float, epsilon: float = 0) -> float:
|
|
27
|
+
"""
|
|
28
|
+
Compute the specular derivative from one-sided directional derivatives.
|
|
29
|
+
|
|
30
|
+
Given real numbers `alpha` and `beta`, the function `A:R^2 -> R` is defined by
|
|
31
|
+
|
|
32
|
+
A(alpha, beta) = (alpha * beta - 1 + sqrt((1 + alpha^2)(1 + beta^2))) / (alpha + beta)
|
|
33
|
+
|
|
34
|
+
if alpha + beta != 0; otherwise, it returns 0.
|
|
35
|
+
|
|
36
|
+
Parameters
|
|
37
|
+
----------
|
|
38
|
+
alpha : float
|
|
39
|
+
One-sided directional derivative.
|
|
40
|
+
beta : float
|
|
41
|
+
One-sided directional derivative.
|
|
42
|
+
|
|
43
|
+
Returns
|
|
44
|
+
-------
|
|
45
|
+
float
|
|
46
|
+
The specular derivative.
|
|
47
|
+
|
|
48
|
+
Raises
|
|
49
|
+
------
|
|
50
|
+
AssertionError
|
|
51
|
+
If `alpha` or `beta` is not a float.
|
|
52
|
+
|
|
53
|
+
Examples
|
|
54
|
+
--------
|
|
55
|
+
>>> A(1.0, 2.0)
|
|
56
|
+
1.2295687883848642
|
|
57
|
+
"""
|
|
58
|
+
alpha = safe_to_float(alpha)
|
|
59
|
+
beta = safe_to_float(beta)
|
|
60
|
+
|
|
61
|
+
assert isinstance(alpha, (int, float, np.floating)), "alpha must be a float. {} is of type {}".format(alpha, type(alpha))
|
|
62
|
+
assert isinstance(beta, (int, float, np.floating)), "beta must be a float. {} is of type {}".format(beta, type(beta))
|
|
63
|
+
|
|
64
|
+
if np.abs(alpha + beta) <= epsilon:
|
|
65
|
+
return 0.0
|
|
66
|
+
else:
|
|
67
|
+
return float((alpha*beta - 1 + np.sqrt((1 + alpha**2)*(1 + beta**2)))/(alpha + beta))
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def specularly_directional_derivative(
|
|
71
|
+
f: Callable[[np.ndarray], float],
|
|
72
|
+
x: Union[float, list, np.ndarray],
|
|
73
|
+
v: Union[float, list, np.ndarray],
|
|
74
|
+
h: float = 1e-6
|
|
75
|
+
) -> float:
|
|
76
|
+
"""
|
|
77
|
+
Approximates the specularly directional derivative of a function `f: R^n -> R` at a point `x`
|
|
78
|
+
in the direction `v`, using finite differences and the averaging operator `A`.
|
|
79
|
+
|
|
80
|
+
This method computes one-sided finite differences from both directions (forward and backward)
|
|
81
|
+
and applies the function `A(alpha, beta)` to return a specularly directional derivative.
|
|
82
|
+
|
|
83
|
+
Parameters
|
|
84
|
+
----------
|
|
85
|
+
f : callable
|
|
86
|
+
A real-valued function defined on an open subset of R^n.
|
|
87
|
+
x : float or array_like
|
|
88
|
+
The point at which the derivative is evaluated.
|
|
89
|
+
v : float or array_like
|
|
90
|
+
The direction in which the derivative is taken.
|
|
91
|
+
h : float, optional
|
|
92
|
+
The step size used in the finite difference approximation (default: 1e-6). Must be positive.
|
|
93
|
+
|
|
94
|
+
Returns
|
|
95
|
+
-------
|
|
96
|
+
float
|
|
97
|
+
The approximated specularly directional derivative of `f` at `x` in the direction `v`.
|
|
98
|
+
|
|
99
|
+
Raises
|
|
100
|
+
------
|
|
101
|
+
AssertionError
|
|
102
|
+
If `x`, `v`, or `h` are not of valid types or if `h <= 0`.
|
|
103
|
+
|
|
104
|
+
Examples
|
|
105
|
+
--------
|
|
106
|
+
>>> import specular_derivative as sd
|
|
107
|
+
>>> import math
|
|
108
|
+
|
|
109
|
+
One-dimensional input:
|
|
110
|
+
>>> f = lambda x: max(x, 0)
|
|
111
|
+
>>> sd.specularly_directional_derivative(f, x=0.0, v=1)
|
|
112
|
+
0.41421356237309515
|
|
113
|
+
|
|
114
|
+
Three-dimensional input:
|
|
115
|
+
>>> f = lambda x: math.sqrt(x[0]**2 + x[1]**2 + x[2]**2)
|
|
116
|
+
>>> sd.specularly_directional_derivative(f, x=[0.0, 0.1, -0.1], v=[1.0, -1.0, 2.0])
|
|
117
|
+
-2.1213203434708223
|
|
118
|
+
"""
|
|
119
|
+
assert isinstance(x, (int, float, list, np.ndarray)), "x must be a int, float, list or a numpy array"
|
|
120
|
+
assert isinstance(v, (int, float, list, np.ndarray)), "v must be a int, float, list or a numpy array"
|
|
121
|
+
assert isinstance(h, (int, float, np.floating)), "h must be a int or float (positive real number)"
|
|
122
|
+
assert h > 0, "h must be positive"
|
|
123
|
+
|
|
124
|
+
x = np.asarray(x, dtype=float)
|
|
125
|
+
v = np.asarray(v, dtype=float)
|
|
126
|
+
|
|
127
|
+
alpha = (f(x + h * v) - f(x))/h
|
|
128
|
+
beta = (f(x) - f(x - h * v))/h
|
|
129
|
+
|
|
130
|
+
return A(alpha, beta)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def specular_derivative(
|
|
134
|
+
f: Callable[[np.ndarray], float],
|
|
135
|
+
x: Union[float, list, np.floating],
|
|
136
|
+
h: float = 1e-6
|
|
137
|
+
) -> float:
|
|
138
|
+
"""
|
|
139
|
+
Approximates the specular derivative of a real-valued function `f: R -> R` at point `x`.
|
|
140
|
+
|
|
141
|
+
This is computed using the `specularly_directional_derivative` function in the direction `v=1.0`.
|
|
142
|
+
|
|
143
|
+
Parameters
|
|
144
|
+
----------
|
|
145
|
+
f : callable
|
|
146
|
+
A real-valued function of a single real variable.
|
|
147
|
+
x : float
|
|
148
|
+
The point at which the derivative is evaluated.
|
|
149
|
+
h : float, optional
|
|
150
|
+
Step size for the finite difference approximation (default: 1e-6).
|
|
151
|
+
|
|
152
|
+
Returns
|
|
153
|
+
-------
|
|
154
|
+
float
|
|
155
|
+
The approximated specular derivative of f at x in direction +1.
|
|
156
|
+
|
|
157
|
+
Raises
|
|
158
|
+
------
|
|
159
|
+
AssertionError
|
|
160
|
+
If x is not a scalar (int or float).
|
|
161
|
+
|
|
162
|
+
Examples
|
|
163
|
+
--------
|
|
164
|
+
>>> import specular_derivative as sd
|
|
165
|
+
|
|
166
|
+
>>> f = lambda x: max(x, 0.0)
|
|
167
|
+
>>> sd.specular_derivative(f, x=0.0)
|
|
168
|
+
0.41421356237309515
|
|
169
|
+
|
|
170
|
+
>>> f = lambda x: abs(x)
|
|
171
|
+
>>> sd.specular_derivative(f, x=0.0)
|
|
172
|
+
0.0
|
|
173
|
+
"""
|
|
174
|
+
assert isinstance(x, (int, float, np.floating)), "x must be a int or float"
|
|
175
|
+
|
|
176
|
+
return specularly_directional_derivative(f, float(x), 1.0, h=h)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def specular_partial_derivative(
|
|
180
|
+
f: Callable[[np.ndarray], float],
|
|
181
|
+
x: Union[list, np.ndarray],
|
|
182
|
+
i: int,
|
|
183
|
+
h: float = 1e-6
|
|
184
|
+
) -> float:
|
|
185
|
+
"""
|
|
186
|
+
Approximates the i-th specular partial derivative of a real-valued function `f: R^n -> R` at point `x` for n > 1.
|
|
187
|
+
|
|
188
|
+
This is computed using the `specularly_directional_derivative` function with the direction of the `i`-th standard basis vector of `R^n`.
|
|
189
|
+
|
|
190
|
+
Parameters
|
|
191
|
+
----------
|
|
192
|
+
f : callable
|
|
193
|
+
A real-valued function defined on R^n.
|
|
194
|
+
x : list or np.ndarray
|
|
195
|
+
The point at which the derivative is evaluated.
|
|
196
|
+
i : int
|
|
197
|
+
The coordinate index (starting from 0) indicating the direction of differentiation.
|
|
198
|
+
h : float, optional
|
|
199
|
+
Step size for the finite difference approximation (default: 1e-6).
|
|
200
|
+
|
|
201
|
+
Returns
|
|
202
|
+
-------
|
|
203
|
+
float
|
|
204
|
+
The approximated i-th partial specular derivative of f at x.
|
|
205
|
+
|
|
206
|
+
Raises
|
|
207
|
+
------
|
|
208
|
+
AssertionError
|
|
209
|
+
If x is not a list or np.ndarray.
|
|
210
|
+
If i is not an integer or out of bounds.
|
|
211
|
+
If x has length less than 2.
|
|
212
|
+
|
|
213
|
+
Examples
|
|
214
|
+
--------
|
|
215
|
+
>>> import specular_derivative as sd
|
|
216
|
+
>>> import math
|
|
217
|
+
|
|
218
|
+
>>> f = lambda x: math.sqrt(x[0]**2 + x[1]**2 + x[2]**2)
|
|
219
|
+
>>> sd.specular_partial_derivative(f, x=[0.1, 2.3, -1.2], i=2)
|
|
220
|
+
-0.4622227292028128
|
|
221
|
+
"""
|
|
222
|
+
assert isinstance(x, (list, np.ndarray)), "x must be a list or a numpy array"
|
|
223
|
+
assert isinstance(i, int), "i must be an integer"
|
|
224
|
+
assert len(x) >= 2, "x must have length at least 2; use the function `specular_derivative` for the one dimension"
|
|
225
|
+
|
|
226
|
+
x = np.asarray(x, dtype=float)
|
|
227
|
+
e_i = np.zeros_like(x)
|
|
228
|
+
e_i[i] = 1.0
|
|
229
|
+
|
|
230
|
+
return specularly_directional_derivative(f, x, e_i, h=h)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def specular_gradient(
|
|
234
|
+
f: Callable[[np.ndarray], float],
|
|
235
|
+
x: Union[list, np.ndarray],
|
|
236
|
+
h: float = 1e-6
|
|
237
|
+
) -> np.ndarray:
|
|
238
|
+
"""
|
|
239
|
+
Approximates the specular gradient of a real-valued function `f: R^n -> R` at point `x` for n > 1.
|
|
240
|
+
|
|
241
|
+
The specular gradient is defined as the vector of all partial specular derivatives
|
|
242
|
+
along the standard basis directions. Each component is computed using the
|
|
243
|
+
`specular_partial_derivative` function.
|
|
244
|
+
|
|
245
|
+
Parameters
|
|
246
|
+
----------
|
|
247
|
+
f : callable
|
|
248
|
+
A real-valued function defined on R^n.
|
|
249
|
+
x : list or np.ndarray
|
|
250
|
+
The point at which the specular gradient is evaluated.
|
|
251
|
+
h : float, optional
|
|
252
|
+
Step size for the finite difference approximation (default: 1e-6).
|
|
253
|
+
|
|
254
|
+
Returns
|
|
255
|
+
-------
|
|
256
|
+
np.ndarray
|
|
257
|
+
A vector (NumPy array) representing the specular gradient of f at x.
|
|
258
|
+
|
|
259
|
+
Examples
|
|
260
|
+
--------
|
|
261
|
+
>>> import specular_derivative as sd
|
|
262
|
+
>>> import numpy as np
|
|
263
|
+
|
|
264
|
+
>>> f = lambda x: np.linalg.norm(x)
|
|
265
|
+
>>> sd.specular_gradient(f, x=[1.4, -3.47, 4.57, 9.9])
|
|
266
|
+
array([ 0.12144298, -0.3010051 , 0.39642458, 0.85877534])
|
|
267
|
+
"""
|
|
268
|
+
result = np.zeros_like(x)
|
|
269
|
+
|
|
270
|
+
for i in range(len(x)):
|
|
271
|
+
result[i] = specular_partial_derivative(f, x, i, h=h)
|
|
272
|
+
|
|
273
|
+
return result
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: specular-differentiation
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Specular differentiation in normed vector spaces and its applications
|
|
5
|
+
Home-page: https://github.com/kyjung2357/specular-differentiation
|
|
6
|
+
Author: Kiyuob Jung
|
|
7
|
+
Author-email: kyjung@msu.edu
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.6
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: author-email
|
|
16
|
+
Dynamic: classifier
|
|
17
|
+
Dynamic: description
|
|
18
|
+
Dynamic: description-content-type
|
|
19
|
+
Dynamic: home-page
|
|
20
|
+
Dynamic: license-file
|
|
21
|
+
Dynamic: requires-python
|
|
22
|
+
Dynamic: summary
|
|
23
|
+
|
|
24
|
+
# Specular Differentiation
|
|
25
|
+
|
|
26
|
+

|
|
27
|
+

|
|
28
|
+
|
|
29
|
+
This repository contains the Python package `specular_diff` and codes for applications:
|
|
30
|
+
|
|
31
|
+
* [**Nonsmooth convex optimization**](#nonsmooth-convex-optimization)
|
|
32
|
+
* Directory: `nonsmooth-convex-opt/`
|
|
33
|
+
* Related reference: [[2]](#references), [[5]](#references)
|
|
34
|
+
|
|
35
|
+
* [**Initial value problems for ordinary differential equations**](#initial-value-problems-for-ordinary-differential-equations)
|
|
36
|
+
* Directory: `numerical-ODE/`
|
|
37
|
+
* Related reference: [[1]](#references), [[3]](#references), [[4]](#references)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
You can install the released version directly from PyPI:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install specular-differentiation
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Introduction
|
|
49
|
+
|
|
50
|
+
*Specular differentiation* generalizes classical differentiation.
|
|
51
|
+
A specular derivative can be understood as the average of the inclination angles of the right and left derivatives.
|
|
52
|
+
In contrast, a symmetric derivative is the average of the right and left derivatives.
|
|
53
|
+
Their difference is illustrated as in the following figure.
|
|
54
|
+
|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
## Applications
|
|
59
|
+
|
|
60
|
+
Specular differentiation is defined in normed vector spaces, allowing for applications in higher-dimensional Euclidean spaces.
|
|
61
|
+
Two applications are provided in this repository.
|
|
62
|
+
|
|
63
|
+
### Nonsmooth convex optimization
|
|
64
|
+
|
|
65
|
+
In [[2]](#references), *the specular gradient method* is introduced for optimizing nonsmooth convex objective functions.
|
|
66
|
+
|
|
67
|
+
### Initial value problems for ordinary differential equations
|
|
68
|
+
|
|
69
|
+
In [[1]](#references), *the specular Euler scheme of Type 5* is introduced for solving ODEs numerically, yielding more accurate numerical solutions than classical schemes: the explicit and implicit Euler schemes and the Crank-Nicolson scheme.
|
|
70
|
+
|
|
71
|
+

|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
## LaTeX notation
|
|
75
|
+
|
|
76
|
+
To use the specular differentiation symbol in your LaTeX document, please refer to the following instructions.
|
|
77
|
+
|
|
78
|
+
### Setup
|
|
79
|
+
|
|
80
|
+
Add the following code to your LaTeX preamble (before `\begin{document}`):
|
|
81
|
+
|
|
82
|
+
```latex
|
|
83
|
+
% Required packages
|
|
84
|
+
\usepackage{graphicx}
|
|
85
|
+
\usepackage{bm}
|
|
86
|
+
|
|
87
|
+
% Definition of Specular Differentiation symbol
|
|
88
|
+
\newcommand\spd[1][.5]{\mathbin{\vcenter{\hbox{\scalebox{#1}{\,$\bm{\wedge}$}}}}}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Usage examples
|
|
92
|
+
|
|
93
|
+
Use the symbol in your document (after `\begin{document}`):
|
|
94
|
+
|
|
95
|
+
```latex
|
|
96
|
+
% A specular derivative in the one-dimensional Euclidean space
|
|
97
|
+
$f^{\spd}(x)$
|
|
98
|
+
|
|
99
|
+
% A specular directional derivative in normed vector spaces
|
|
100
|
+
$\partial^{\spd}_v f(x)$
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
## References
|
|
105
|
+
|
|
106
|
+
[1] K. Jung. *Nonlinear numerical schemes using specular differentiation for initial value problems of first-order ordinary differential equations*. arXiv preprint arXiv:??, 2025.
|
|
107
|
+
|
|
108
|
+
[2] K. Jung. *Specular differentiation in normed vector spaces and its applications to nonsmooth convex optimization*. arXiv preprint arXiv:??, 2025.
|
|
109
|
+
|
|
110
|
+
[3] K. Jung and J. Oh. [*The specular derivative*](https://arxiv.org/abs/2210.06062). *arXiv preprint arXiv:2210.06062*, 2022.
|
|
111
|
+
|
|
112
|
+
[4] K. Jung and J. Oh. [*The wave equation with specular derivatives*](https://arxiv.org/abs/2210.06933). *arXiv preprint arXiv:2210.06933*, 2022.
|
|
113
|
+
|
|
114
|
+
[5] K. Jung and J. Oh. [*Nonsmooth convex optimization using the specular gradient method with root-linear convergence*](https://arxiv.org/abs/2412.20747). *arXiv preprint arXiv:2210.06933*, 2024.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
setup.py
|
|
4
|
+
specular_diff/__init__.py
|
|
5
|
+
specular_diff/specular_derivative.py
|
|
6
|
+
specular_differentiation.egg-info/PKG-INFO
|
|
7
|
+
specular_differentiation.egg-info/SOURCES.txt
|
|
8
|
+
specular_differentiation.egg-info/dependency_links.txt
|
|
9
|
+
specular_differentiation.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
specular_diff
|