astrocolor 0.1.0__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.
- astrocolor-0.1.0/LICENSE.txt +21 -0
- astrocolor-0.1.0/PKG-INFO +125 -0
- astrocolor-0.1.0/README.md +104 -0
- astrocolor-0.1.0/pyproject.toml +41 -0
- astrocolor-0.1.0/src/astrocolor/__init__.py +39 -0
- astrocolor-0.1.0/src/astrocolor/algebra.py +101 -0
- astrocolor-0.1.0/src/astrocolor/auxiliary.py +803 -0
- astrocolor-0.1.0/src/astrocolor/color.py +342 -0
- astrocolor-0.1.0/src/astrocolor/convolution.py +94 -0
- astrocolor-0.1.0/src/astrocolor/core.py +472 -0
- astrocolor-0.1.0/src/astrocolor/data/Sun_CALSPEC.npz +0 -0
- astrocolor-0.1.0/src/astrocolor/data/Vega_CALSPEC.npz +0 -0
- astrocolor-0.1.0/src/astrocolor/data_manager.py +3 -0
- astrocolor-0.1.0/src/astrocolor/errors.py +104 -0
- astrocolor-0.1.0/src/astrocolor/filter_objects.py +248 -0
- astrocolor-0.1.0/src/astrocolor/filters/CIE_1931_2deg.x.txt +95 -0
- astrocolor-0.1.0/src/astrocolor/filters/CIE_1931_2deg.y.txt +95 -0
- astrocolor-0.1.0/src/astrocolor/filters/CIE_1931_2deg.z.txt +58 -0
- astrocolor-0.1.0/src/astrocolor/filters/Generic_Bessell.B.datA +21 -0
- astrocolor-0.1.0/src/astrocolor/filters/Generic_Bessell.R.datA +24 -0
- astrocolor-0.1.0/src/astrocolor/filters/Generic_Bessell.U.datA +25 -0
- astrocolor-0.1.0/src/astrocolor/filters/Generic_Bessell.V.datA +24 -0
- astrocolor-0.1.0/src/astrocolor/filters/SLOAN_SDSS.g.datA +89 -0
- astrocolor-0.1.0/src/astrocolor/filters/SLOAN_SDSS.r.datA +75 -0
- astrocolor-0.1.0/src/astrocolor/photospectral_objects.py +202 -0
- astrocolor-0.1.0/src/astrocolor/physical_models.py +73 -0
- astrocolor-0.1.0/src/astrocolor/py.typed +0 -0
- astrocolor-0.1.0/src/astrocolor/spectral_objects.py +458 -0
- astrocolor-0.1.0/src/astrocolor/spectral_reconstruction.py +240 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Askaniy Anpilogov
|
|
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,125 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: astrocolor
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Library to perform spectral reconstruction, calculate synthetic photometry and colors.
|
|
5
|
+
Author: Askaniy Anpilogov
|
|
6
|
+
Author-email: Askaniy Anpilogov <aaskaniy@gmail.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE.txt
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Requires-Dist: numpy>=2.4.4
|
|
14
|
+
Requires-Dist: scipy>=1.17.1
|
|
15
|
+
Requires-Python: >=3.12
|
|
16
|
+
Project-URL: Homepage, https://github.com/Askaniy/AstroColor
|
|
17
|
+
Project-URL: Repository, https://github.com/Askaniy/AstroColor
|
|
18
|
+
Project-URL: Issues, https://github.com/Askaniy/AstroColor/issues
|
|
19
|
+
Project-URL: Changelog, https://github.com/Askaniy/AstroColor/releases
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# AstroColor
|
|
23
|
+
|
|
24
|
+
A Python library for converting between photometric systems, true color calculation, and space image processing.
|
|
25
|
+
|
|
26
|
+
It performs synthetic photometry on low-resolution (5-nm wavelength grid step) spectra as well as spectral reconstruction from measurements in filters based on Tikhonov regularization.
|
|
27
|
+
|
|
28
|
+
**Pre-alpha version! Do not use!**
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
Use AstroColor in a virtual environment:
|
|
34
|
+
```sh
|
|
35
|
+
python3 -m venv .venv
|
|
36
|
+
.venv/bin/pip install git+https://github.com/Askaniy/AstroColor.git
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Or add AstroColor to your [uv](https://github.com/astral-sh/uv) project:
|
|
40
|
+
```sh
|
|
41
|
+
uv add git+https://github.com/Askaniy/AstroColor.git
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## Key features
|
|
46
|
+
|
|
47
|
+
- Calculate synthetic photometry
|
|
48
|
+
```py
|
|
49
|
+
import astrocolor as ac
|
|
50
|
+
|
|
51
|
+
spectrum = ac.Spectrum(
|
|
52
|
+
wavelength_nm=[400, 500, 600, 700],
|
|
53
|
+
spectral_dist=[1, 2, 2, 1]
|
|
54
|
+
)
|
|
55
|
+
v_band = ac.Filter.get('Generic_Bessell.V')
|
|
56
|
+
flux_value, flux_error = ac.observe(spectrum, v_band)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- Create a filter system
|
|
60
|
+
```py
|
|
61
|
+
johnson_system = ac.FilterSet.get(
|
|
62
|
+
'Generic_Bessell.B',
|
|
63
|
+
'Generic_Bessell.V',
|
|
64
|
+
'Generic_Bessell.R'
|
|
65
|
+
)
|
|
66
|
+
photospectrum_BVR = ac.observe(spectrum, johnson_system)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- Reconstruct photometry measurements into a smooth spectrum
|
|
70
|
+
```py
|
|
71
|
+
reconstructed = ac.spectral_reconstruction(photospectrum_BVR, requested_wavelengths=[400, 700])
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
- Convert measurements directly between photometric systems
|
|
75
|
+
```py
|
|
76
|
+
sloan_system = ac.FilterSet.get('SLOAN_SDSS.g', 'SLOAN_SDSS.r')
|
|
77
|
+
photospectrum_gr = ac.observe(photospectrum_BVR, sloan_system)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
- Work on your wavelengths
|
|
81
|
+
```py
|
|
82
|
+
custom_filter_set = ac.Filter.monochromatic(656.279) | ac.Filter.monochromatic(486.135)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- Calculate true colors
|
|
86
|
+
```py
|
|
87
|
+
color_xyz = ac.ColorPoint.from_spectral_data(ac.sun_CALSPEC)
|
|
88
|
+
color_system = ac.ColorSystem('sRGB', 'Illuminant E') # recommended
|
|
89
|
+
color_rgb = color_xyz.to_color_system(color_system)
|
|
90
|
+
color_rgb.maximize_brightness = True
|
|
91
|
+
color_html = color_rgb.to_html()
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
- Model spectra
|
|
95
|
+
```py
|
|
96
|
+
bb_3000K = ac.BlackBodyModel(3000).determine_at_wavelengths([400, 700])
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
- Process images via spectral cube reconstruction
|
|
100
|
+
```py
|
|
101
|
+
# coming soon after debugging
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
- Error propagation with covariance matrices
|
|
105
|
+
```py
|
|
106
|
+
# coming soon after debugging
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
## History
|
|
112
|
+
|
|
113
|
+
[TrueColorTools](https://github.com/Askaniy/TrueColorTools) were created in 2020 to resolve disputes regarding the color of celestial bodies.
|
|
114
|
+
It features a graphical user interface and a user-expandable spectral database.
|
|
115
|
+
Over time, the core of the program became self-contained enough to be spun off into a library.
|
|
116
|
+
The refactoring took place in 2026; it opens up a general astronomical application.
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
## For developers
|
|
120
|
+
|
|
121
|
+
Use `uv sync --group dev` to set the environment and build the library.
|
|
122
|
+
Use `uv run pytest` for testing.
|
|
123
|
+
Use `\dev` folder for local experiments.
|
|
124
|
+
|
|
125
|
+
Any changes suggested by AI must be thoroughly reviewed by the person who generated them. The responsibility always lies with the person.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# AstroColor
|
|
2
|
+
|
|
3
|
+
A Python library for converting between photometric systems, true color calculation, and space image processing.
|
|
4
|
+
|
|
5
|
+
It performs synthetic photometry on low-resolution (5-nm wavelength grid step) spectra as well as spectral reconstruction from measurements in filters based on Tikhonov regularization.
|
|
6
|
+
|
|
7
|
+
**Pre-alpha version! Do not use!**
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
Use AstroColor in a virtual environment:
|
|
13
|
+
```sh
|
|
14
|
+
python3 -m venv .venv
|
|
15
|
+
.venv/bin/pip install git+https://github.com/Askaniy/AstroColor.git
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Or add AstroColor to your [uv](https://github.com/astral-sh/uv) project:
|
|
19
|
+
```sh
|
|
20
|
+
uv add git+https://github.com/Askaniy/AstroColor.git
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## Key features
|
|
25
|
+
|
|
26
|
+
- Calculate synthetic photometry
|
|
27
|
+
```py
|
|
28
|
+
import astrocolor as ac
|
|
29
|
+
|
|
30
|
+
spectrum = ac.Spectrum(
|
|
31
|
+
wavelength_nm=[400, 500, 600, 700],
|
|
32
|
+
spectral_dist=[1, 2, 2, 1]
|
|
33
|
+
)
|
|
34
|
+
v_band = ac.Filter.get('Generic_Bessell.V')
|
|
35
|
+
flux_value, flux_error = ac.observe(spectrum, v_band)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
- Create a filter system
|
|
39
|
+
```py
|
|
40
|
+
johnson_system = ac.FilterSet.get(
|
|
41
|
+
'Generic_Bessell.B',
|
|
42
|
+
'Generic_Bessell.V',
|
|
43
|
+
'Generic_Bessell.R'
|
|
44
|
+
)
|
|
45
|
+
photospectrum_BVR = ac.observe(spectrum, johnson_system)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- Reconstruct photometry measurements into a smooth spectrum
|
|
49
|
+
```py
|
|
50
|
+
reconstructed = ac.spectral_reconstruction(photospectrum_BVR, requested_wavelengths=[400, 700])
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- Convert measurements directly between photometric systems
|
|
54
|
+
```py
|
|
55
|
+
sloan_system = ac.FilterSet.get('SLOAN_SDSS.g', 'SLOAN_SDSS.r')
|
|
56
|
+
photospectrum_gr = ac.observe(photospectrum_BVR, sloan_system)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- Work on your wavelengths
|
|
60
|
+
```py
|
|
61
|
+
custom_filter_set = ac.Filter.monochromatic(656.279) | ac.Filter.monochromatic(486.135)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
- Calculate true colors
|
|
65
|
+
```py
|
|
66
|
+
color_xyz = ac.ColorPoint.from_spectral_data(ac.sun_CALSPEC)
|
|
67
|
+
color_system = ac.ColorSystem('sRGB', 'Illuminant E') # recommended
|
|
68
|
+
color_rgb = color_xyz.to_color_system(color_system)
|
|
69
|
+
color_rgb.maximize_brightness = True
|
|
70
|
+
color_html = color_rgb.to_html()
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
- Model spectra
|
|
74
|
+
```py
|
|
75
|
+
bb_3000K = ac.BlackBodyModel(3000).determine_at_wavelengths([400, 700])
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
- Process images via spectral cube reconstruction
|
|
79
|
+
```py
|
|
80
|
+
# coming soon after debugging
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
- Error propagation with covariance matrices
|
|
84
|
+
```py
|
|
85
|
+
# coming soon after debugging
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
## History
|
|
91
|
+
|
|
92
|
+
[TrueColorTools](https://github.com/Askaniy/TrueColorTools) were created in 2020 to resolve disputes regarding the color of celestial bodies.
|
|
93
|
+
It features a graphical user interface and a user-expandable spectral database.
|
|
94
|
+
Over time, the core of the program became self-contained enough to be spun off into a library.
|
|
95
|
+
The refactoring took place in 2026; it opens up a general astronomical application.
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
## For developers
|
|
99
|
+
|
|
100
|
+
Use `uv sync --group dev` to set the environment and build the library.
|
|
101
|
+
Use `uv run pytest` for testing.
|
|
102
|
+
Use `\dev` folder for local experiments.
|
|
103
|
+
|
|
104
|
+
Any changes suggested by AI must be thoroughly reviewed by the person who generated them. The responsibility always lies with the person.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["uv_build>=0.11.20,<0.12.0"]
|
|
3
|
+
build-backend = "uv_build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "astrocolor"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Library to perform spectral reconstruction, calculate synthetic photometry and colors."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE.txt"]
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Askaniy Anpilogov", email = "aaskaniy@gmail.com" },
|
|
14
|
+
]
|
|
15
|
+
requires-python = ">=3.12"
|
|
16
|
+
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Programming Language :: Python :: 3.14",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
dependencies = [
|
|
25
|
+
"numpy>=2.4.4",
|
|
26
|
+
"scipy>=1.17.1",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Homepage = "https://github.com/Askaniy/AstroColor"
|
|
31
|
+
Repository = "https://github.com/Askaniy/AstroColor"
|
|
32
|
+
Issues = "https://github.com/Askaniy/AstroColor/issues"
|
|
33
|
+
Changelog = "https://github.com/Askaniy/AstroColor/releases"
|
|
34
|
+
|
|
35
|
+
[dependency-groups]
|
|
36
|
+
dev = [
|
|
37
|
+
"pytest>=9.1.1",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[tool.pytest.ini_options]
|
|
41
|
+
testpaths = ["tests", "src/astrocolor/tests"]
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from .spectral_objects import Spectrum, SpectralSet, SpectralCube
|
|
2
|
+
from .photospectral_objects import Photospectrum, PhotospectralSet, PhotospectralCube
|
|
3
|
+
from .spectral_reconstruction import (
|
|
4
|
+
ReconstructedSpectrum,
|
|
5
|
+
ReconstructedSpectralSet,
|
|
6
|
+
ReconstructedSpectralCube,
|
|
7
|
+
spectral_reconstruction,
|
|
8
|
+
)
|
|
9
|
+
from .filter_objects import Filter, FilterSet
|
|
10
|
+
from .convolution import observe, scale_spectrum
|
|
11
|
+
from .color import ColorSystem, ColorPoint, ColorLine, ColorImage, visible_range
|
|
12
|
+
from .physical_models import sun_CALSPEC, vega_CALSPEC, BlackBodyModel
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# API namespace
|
|
16
|
+
__all__ = (
|
|
17
|
+
'Spectrum',
|
|
18
|
+
'SpectralSet',
|
|
19
|
+
'SpectralCube',
|
|
20
|
+
'Photospectrum',
|
|
21
|
+
'PhotospectralSet',
|
|
22
|
+
'PhotospectralCube',
|
|
23
|
+
'ReconstructedSpectrum',
|
|
24
|
+
'ReconstructedSpectralSet',
|
|
25
|
+
'ReconstructedSpectralCube',
|
|
26
|
+
'spectral_reconstruction',
|
|
27
|
+
'Filter',
|
|
28
|
+
'FilterSet',
|
|
29
|
+
'observe',
|
|
30
|
+
'scale_spectrum',
|
|
31
|
+
'ColorSystem',
|
|
32
|
+
'ColorPoint',
|
|
33
|
+
'ColorLine',
|
|
34
|
+
'ColorImage',
|
|
35
|
+
'visible_range',
|
|
36
|
+
'sun_CALSPEC',
|
|
37
|
+
'vega_CALSPEC',
|
|
38
|
+
'BlackBodyModel'
|
|
39
|
+
)
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import numpy.typing as npt
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def make_same_ndim(arr1: npt.ArrayLike, arr2: npt.ArrayLike):
|
|
7
|
+
""" Equalizes the arrays dimensions along spatial axes to make it possible to broadcast """
|
|
8
|
+
arr1 = np.asarray(arr1)
|
|
9
|
+
arr2 = np.asarray(arr2)
|
|
10
|
+
if (ndim_delta := arr2.ndim - arr1.ndim) != 0:
|
|
11
|
+
if ndim_delta > 0:
|
|
12
|
+
arr1 = arr1.reshape(arr1.shape + (1,)*ndim_delta)
|
|
13
|
+
else:
|
|
14
|
+
arr2 = arr2.reshape(arr2.shape + (1,)*(-ndim_delta))
|
|
15
|
+
return arr1, arr2
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# 1. Addition
|
|
19
|
+
|
|
20
|
+
def add_value(mean_x, mean_y):
|
|
21
|
+
mean_x, mean_y = make_same_ndim(mean_x, mean_y)
|
|
22
|
+
return mean_x + mean_y
|
|
23
|
+
|
|
24
|
+
def add_error(mean_x, cov_x, mean_y, cov_y):
|
|
25
|
+
if cov_x is None:
|
|
26
|
+
return cov_y
|
|
27
|
+
elif cov_y is None:
|
|
28
|
+
return cov_x
|
|
29
|
+
else:
|
|
30
|
+
cov_x, cov_y = make_same_ndim(cov_x, cov_y)
|
|
31
|
+
return cov_x + cov_y
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# 2. Subtraction
|
|
35
|
+
|
|
36
|
+
def sub_value(mean_x, mean_y):
|
|
37
|
+
mean_x, mean_y = make_same_ndim(mean_x, mean_y)
|
|
38
|
+
return mean_x - mean_y
|
|
39
|
+
|
|
40
|
+
def sub_error(mean_x, cov_x, mean_y, cov_y):
|
|
41
|
+
return add_error(mean_x, cov_x, mean_y, cov_y)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# 3. Multiplication
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def mul_value(mean_x, mean_y):
|
|
48
|
+
try:
|
|
49
|
+
# Numeric and same-ndim numpy arrays cases
|
|
50
|
+
return mean_x * mean_y
|
|
51
|
+
except ValueError:
|
|
52
|
+
# Different ndim case
|
|
53
|
+
mean_x = np.asarray(mean_x)
|
|
54
|
+
mean_y = np.asarray(mean_y)
|
|
55
|
+
if mean_y.ndim > mean_x.ndim:
|
|
56
|
+
mean_x, mean_y = mean_y, mean_x
|
|
57
|
+
return (mean_x.T * mean_y).T
|
|
58
|
+
|
|
59
|
+
def mul_error(mean_x, cov_x, mean_y, cov_y):
|
|
60
|
+
if cov_x is None and cov_y is None:
|
|
61
|
+
return None
|
|
62
|
+
else:
|
|
63
|
+
n = mean_x.shape[0]
|
|
64
|
+
cov_z = np.zeros((n, n)) # TODO: fix the case of x.ndim != y.ndim
|
|
65
|
+
if cov_x is not None:
|
|
66
|
+
diag_y = np.diag(mean_y)
|
|
67
|
+
cov_z += diag_y @ cov_x @ diag_y
|
|
68
|
+
if cov_y is not None:
|
|
69
|
+
diag_x = np.diag(mean_x)
|
|
70
|
+
cov_z += diag_x @ cov_y @ diag_x
|
|
71
|
+
return cov_z
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# 4. Division
|
|
75
|
+
|
|
76
|
+
@staticmethod
|
|
77
|
+
def div_value(mean_x, mean_y):
|
|
78
|
+
try:
|
|
79
|
+
# Numeric and same-ndim numpy arrays cases
|
|
80
|
+
return mean_x / mean_y
|
|
81
|
+
except ValueError:
|
|
82
|
+
# Different ndim case
|
|
83
|
+
mean_x = np.asarray(mean_x)
|
|
84
|
+
mean_y = np.asarray(mean_y)
|
|
85
|
+
if mean_y.ndim > mean_x.ndim:
|
|
86
|
+
mean_x, mean_y = mean_y, mean_x
|
|
87
|
+
return (mean_x.T / mean_y).T
|
|
88
|
+
|
|
89
|
+
def div_error(mean_x, cov_x, mean_y, cov_y):
|
|
90
|
+
if cov_x is None and cov_y is None:
|
|
91
|
+
return None
|
|
92
|
+
else:
|
|
93
|
+
n = mean_x.shape[0]
|
|
94
|
+
cov_z = np.zeros((n, n)) # TODO: fix the case of x.ndim != y.ndim
|
|
95
|
+
if cov_x is not None:
|
|
96
|
+
cov_z += cov_x
|
|
97
|
+
if cov_y is not None:
|
|
98
|
+
diag_z = np.diag(div_value(mean_x, mean_y))
|
|
99
|
+
cov_z += diag_z @ cov_y @ diag_z
|
|
100
|
+
diag_y_inv = np.diag(1 / mean_y)
|
|
101
|
+
return diag_y_inv @ cov_z @ diag_y_inv
|