ararpy 0.1.35__tar.gz → 0.1.37__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.
- {ararpy-0.1.35 → ararpy-0.1.37}/PKG-INFO +1 -1
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/__init__.py +2 -3
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/calc/basic.py +12 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/calc/raw_funcs.py +3 -3
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/calc/regression.py +207 -100
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/files/calc_file.py +35 -34
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/files/raw_file.py +97 -131
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/smp/info.py +2 -2
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/smp/initial.py +14 -11
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/smp/json.py +2 -2
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/smp/raw.py +4 -4
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/smp/sample.py +59 -70
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/smp/style.py +4 -1
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy.egg-info/PKG-INFO +1 -1
- {ararpy-0.1.35 → ararpy-0.1.37}/setup.py +1 -1
- {ararpy-0.1.35 → ararpy-0.1.37}/LICENSE +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/README.md +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/Example - Check arr.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/Example - Granite Cooling History.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/Example - Plot temperature calibration.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/Example - Show MDD results.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/Example - Show all Kfs age spectra.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/Example - Show random walk results.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/Example - Tc calculation.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/calc/__init__.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/calc/age.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/calc/arr.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/calc/corr.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/calc/err.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/calc/histogram.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/calc/isochron.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/calc/jvalue.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/calc/plot.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/calc/spectra.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/022_VU124-M11a.ahd +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/20WHA0103.age +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/22WHA0078.xls +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/22WHA0433.age +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/22WHA0433.arr +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/22WHA0433.full.xls +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/24WHN0001-51-592.XLS +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/AHD.input-filter +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/ArAr.calc +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/ArArCALC.age +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/NGX-600 - Copy.TXT +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/NGX-600.TXT +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/NGX-XLS.input-filter +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/Qtegra-exported-xls.input-filter +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/S01-239.csv +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/WH01.irra +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/WHA.pdf +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/raw_example.xls +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/examples/sample-default.smp +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/files/__init__.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/files/arr_file.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/files/basic.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/files/new_file.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/files/xls.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/smp/EXPORT_TO_PDF_DATA_PROPERTIES.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/smp/__init__.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/smp/basic.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/smp/calculation.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/smp/consts.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/smp/corr.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/smp/diffusion_funcs.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/smp/export.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/smp/plots.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/smp/table.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/test.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/thermo/__init__.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/thermo/arrhenius.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/thermo/atomic_level_random_walk.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy/thermo/basic.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy.egg-info/SOURCES.txt +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy.egg-info/dependency_links.txt +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/ararpy.egg-info/top_level.txt +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/setup.cfg +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/tests/test.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/tests/test2.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/tests/test_error_correlation.py +0 -0
- {ararpy-0.1.35 → ararpy-0.1.37}/tests/test_regression_methods.py +0 -0
|
@@ -16,10 +16,10 @@ from . import calc, smp, files, thermo, test
|
|
|
16
16
|
""" Information """
|
|
17
17
|
|
|
18
18
|
name = 'ararpy'
|
|
19
|
-
version = '0.1.
|
|
19
|
+
version = '0.1.37'
|
|
20
20
|
__version__ = version
|
|
21
21
|
full_version = version
|
|
22
|
-
last_update = '2025-12-
|
|
22
|
+
last_update = '2025-12-12'
|
|
23
23
|
|
|
24
24
|
""" ArArPy Functions """
|
|
25
25
|
|
|
@@ -141,6 +141,5 @@ RawData.get_sequence = smp.raw.get_sequence
|
|
|
141
141
|
RawData.to_sample = smp.initial.from_raw_data
|
|
142
142
|
RawData.get_unknown = lambda _raw: smp.raw.get_sequence(_raw, True, 'is_unknown', unique=False)
|
|
143
143
|
RawData.get_blank = lambda _raw: smp.raw.get_sequence(_raw, True, 'is_blank', unique=False)
|
|
144
|
-
RawData.get_air = lambda _raw: smp.raw.get_sequence(_raw, True, 'is_air', unique=False)
|
|
145
144
|
Sequence.get_data_df = lambda _seq: pd.DataFrame(_seq.data)
|
|
146
145
|
Sequence.get_flag_df = lambda _seq: pd.DataFrame(_seq.flag)
|
|
@@ -57,6 +57,18 @@ def get_datetime(t_year: int, t_month: int, t_day: int, t_hour: int, t_min: int,
|
|
|
57
57
|
return ts - base
|
|
58
58
|
|
|
59
59
|
|
|
60
|
+
def get_timestring(timestamp: int = 0, base=None):
|
|
61
|
+
"""
|
|
62
|
+
:param timestamp: timestamp (utz)
|
|
63
|
+
:param base: base time [y, m, d, h, m]
|
|
64
|
+
:return:
|
|
65
|
+
"""
|
|
66
|
+
if base is None:
|
|
67
|
+
base = [1970, 1, 1, 0, 0]
|
|
68
|
+
ts = timestamp + datetime(*base, tzinfo=timezone.utc).timestamp()
|
|
69
|
+
return datetime.fromtimestamp(ts, tz=timezone.utc).isoformat(timespec='seconds')
|
|
70
|
+
|
|
71
|
+
|
|
60
72
|
def merge_dicts(a: dict, b: dict):
|
|
61
73
|
"""
|
|
62
74
|
a and b, two dictionary. Return updated a
|
|
@@ -30,8 +30,8 @@ def get_raw_data_regression_results(points_data, unselected: list = None):
|
|
|
30
30
|
|
|
31
31
|
"""
|
|
32
32
|
def power(a0, a1):
|
|
33
|
-
return regression.power(a0, a1)
|
|
34
|
-
|
|
33
|
+
# return regression.power(a0, a1)
|
|
34
|
+
raise ValueError("Deprecated regression")
|
|
35
35
|
# if unselected is None:
|
|
36
36
|
# unselected = []
|
|
37
37
|
# linesData = []
|
|
@@ -42,9 +42,9 @@ def get_raw_data_regression_results(points_data, unselected: list = None):
|
|
|
42
42
|
power, regression.average]
|
|
43
43
|
# size = 50
|
|
44
44
|
# lines_x = [(max(x + un_x) - 0) / size * i for i in range(size + 1)]
|
|
45
|
+
x, y = transpose(points_data, ignore=False)
|
|
45
46
|
for i in range(len(reg_handler)):
|
|
46
47
|
try:
|
|
47
|
-
x, y = transpose(points_data, ignore=False)
|
|
48
48
|
res = reg_handler[i](a0=y, a1=x)
|
|
49
49
|
# line_data = transpose([lines_x, res[7](lines_x)])
|
|
50
50
|
line_results = res[0:4]
|
|
@@ -16,7 +16,7 @@ import traceback
|
|
|
16
16
|
import numpy as np
|
|
17
17
|
import pandas as pd
|
|
18
18
|
from scipy.stats import distributions
|
|
19
|
-
from scipy.optimize import
|
|
19
|
+
from scipy.optimize import minimize_scalar
|
|
20
20
|
import warnings
|
|
21
21
|
from scipy.optimize import minimize
|
|
22
22
|
warnings.simplefilter(action="ignore", category=RuntimeWarning)
|
|
@@ -495,22 +495,25 @@ def linest(a0: list, a1: list, *args):
|
|
|
495
495
|
# calculate Y values base on the fitted formula
|
|
496
496
|
estimate_y = np.matmul(x, beta)
|
|
497
497
|
resid = (estimate_y - y) ** 2
|
|
498
|
-
reg = (estimate_y - np.mean(
|
|
499
|
-
ssresid = resid.sum()
|
|
500
|
-
ssreg = reg.sum()
|
|
501
|
-
sstotal =
|
|
498
|
+
reg = (estimate_y - np.mean(y)) ** 2
|
|
499
|
+
ssresid = resid.sum() # 残差平方和
|
|
500
|
+
ssreg = reg.sum() # 回归平方和
|
|
501
|
+
sstotal = ((y - np.mean(y)) ** 2).sum()
|
|
502
|
+
r2 = ssreg / sstotal if sstotal != 0 else np.inf
|
|
503
|
+
|
|
502
504
|
df = m - n
|
|
503
|
-
m_ssresid = ssresid / df
|
|
504
|
-
|
|
505
|
-
|
|
505
|
+
m_ssresid = ssresid / df # 均方残差,与加权平均中的MSWD对应
|
|
506
|
+
cov_beta = m_ssresid * inv_xtx
|
|
507
|
+
se_beta = np.diagonal(cov_beta) ** .5
|
|
508
|
+
|
|
509
|
+
beta = beta.flatten()
|
|
506
510
|
rse_beta = se_beta / beta
|
|
507
|
-
r2 = ssreg / sstotal if sstotal != 0 else np.inf
|
|
508
511
|
|
|
509
512
|
def get_adjusted_y(*args):
|
|
510
513
|
args = [[1] * len(args[0]), *args]
|
|
511
514
|
return [sum([beta[i] * args[i][j] for i in range(len(beta))]) for j in range(len(args[0]))]
|
|
512
515
|
|
|
513
|
-
return beta[0], se_beta[0], rse_beta[0] * 100, r2, m_ssresid, beta,
|
|
516
|
+
return beta[0], se_beta[0], abs(rse_beta[0]) * 100, r2, m_ssresid, beta, cov_beta, get_adjusted_y, m_ssresid
|
|
514
517
|
|
|
515
518
|
|
|
516
519
|
def average(a0: list, a1=None):
|
|
@@ -535,12 +538,12 @@ def average(a0: list, a1=None):
|
|
|
535
538
|
m_ssresid = ssresid / df
|
|
536
539
|
r2 = ssreg / sstotal if sstotal != 0 else 1 # r2 = ssreg / sstotal
|
|
537
540
|
|
|
538
|
-
|
|
539
|
-
|
|
541
|
+
k6 = [[sum([(i - k0) ** 2 for i in a0]) / df]]
|
|
542
|
+
k1 = pow(k6[0][0], 0.5) # standard deviation
|
|
543
|
+
k2 = k1 / abs(k0) * 100 if k0 != 0 else 0 # relative standard error
|
|
540
544
|
k3 = r2 # determination coefficient
|
|
541
|
-
k4 = 'MSWD'
|
|
545
|
+
k4 = m_ssresid # 'MSWD'
|
|
542
546
|
k5 = [k0]
|
|
543
|
-
k6 = [k1]
|
|
544
547
|
k8 = m_ssresid
|
|
545
548
|
|
|
546
549
|
def get_adjusted_y(x: list):
|
|
@@ -737,7 +740,7 @@ def quadratic(a0: list, a1: list):
|
|
|
737
740
|
"""
|
|
738
741
|
# y = b + m1 * x + m2 * x ^ 2
|
|
739
742
|
k = list(linest(a0, a1, [i ** 2 for i in a1]))
|
|
740
|
-
|
|
743
|
+
[b, m1, m2] = k[5]
|
|
741
744
|
|
|
742
745
|
def get_adjusted_y(x: list):
|
|
743
746
|
return [b + m1 * _x + m2 * _x ** 2 for _x in x]
|
|
@@ -756,7 +759,7 @@ def polynomial(a0: list, a1: list, degree: int = 5):
|
|
|
756
759
|
"""
|
|
757
760
|
# y = b + m1 * x + m2 * x ^ 2 + ... + m[n] * x ^ n
|
|
758
761
|
k = list(linest(a0, *[[j ** (i + 1) for j in a1] for i in range(degree)]))
|
|
759
|
-
|
|
762
|
+
beta = k[5]
|
|
760
763
|
|
|
761
764
|
def get_adjusted_y(x: list):
|
|
762
765
|
return [sum([beta[i] * _x ** i for i in range(degree + 1)]) for _x in x]
|
|
@@ -766,6 +769,7 @@ def polynomial(a0: list, a1: list, degree: int = 5):
|
|
|
766
769
|
return k
|
|
767
770
|
|
|
768
771
|
|
|
772
|
+
### Deprecated
|
|
769
773
|
def logest(a0: list, a1: list):
|
|
770
774
|
"""
|
|
771
775
|
:param a0: known_y's, y = b * m ^ x
|
|
@@ -775,15 +779,19 @@ def logest(a0: list, a1: list):
|
|
|
775
779
|
# y = b * m ^ x, Microsoft Excel LOGEST function, ln(y) = ln(b) + ln(m) * x
|
|
776
780
|
a0 = [np.log(i) for i in a0] # ln(y)
|
|
777
781
|
linest_res = linest(a0, a1)
|
|
778
|
-
lnb, selnb, rseb, r2, mswd,
|
|
782
|
+
lnb, selnb, rseb, r2, mswd, beta, cov_beta = linest_res[0:7]
|
|
783
|
+
lnb, lnm = beta
|
|
784
|
+
selnb, selnm = np.diagonal(cov_beta) ** .5
|
|
785
|
+
|
|
779
786
|
b = np.exp(lnb)
|
|
780
787
|
m = np.exp(lnm)
|
|
781
788
|
sem = np.exp(lnm) * selnm
|
|
782
789
|
seb = np.exp(lnb) * selnb # Excel.Logest function do not consider the error propagation
|
|
783
|
-
rseb = seb / b * 100
|
|
790
|
+
rseb = seb / abs(b) * 100
|
|
784
791
|
return b, seb, rseb, r2, mswd, m, sem
|
|
785
792
|
|
|
786
793
|
|
|
794
|
+
### Deprecated
|
|
787
795
|
def power(a0: list, a1: list):
|
|
788
796
|
"""
|
|
789
797
|
:param a0: known_y's, y = a * x ^ b + c
|
|
@@ -841,7 +849,9 @@ def power(a0: list, a1: list):
|
|
|
841
849
|
raise IndexError
|
|
842
850
|
|
|
843
851
|
f = linest(a0, [_x ** b for _x in a1])
|
|
844
|
-
|
|
852
|
+
beta, cov_beta = f[5:7]
|
|
853
|
+
c, a = beta
|
|
854
|
+
sec, sea = np.diagonal(cov_beta) ** .5
|
|
845
855
|
|
|
846
856
|
calculated_y = [_pow_func(i, a, b, c) for i in a1]
|
|
847
857
|
resid = [(calculated_y[i] - a0[i]) ** 2 for i in range(len(a0))]
|
|
@@ -862,104 +872,193 @@ def power(a0: list, a1: list):
|
|
|
862
872
|
errfx = pow(sum([i ** 2 for i in a1]) / (dp * sum([i ** 2 for i in a1]) - sum(a1) ** 2), 0.5)
|
|
863
873
|
# seb = errfz * sey = errfz * ssresid / df -> se_intercept = sey * errfx = seb / errfz * errfx
|
|
864
874
|
se_intercept = sec / errfz * errfx
|
|
865
|
-
rse_intercept = se_intercept / intercept * 100
|
|
875
|
+
rse_intercept = se_intercept / abs(intercept) * 100
|
|
876
|
+
|
|
877
|
+
|
|
878
|
+
exp_beta = [a, b, c]
|
|
879
|
+
exp_cov_beta = [
|
|
880
|
+
[cov_beta[1][1], 0, cov_beta[1][0]],
|
|
881
|
+
[0, 0, 0],
|
|
882
|
+
[cov_beta[0][1], 0, cov_beta[0][0]],
|
|
883
|
+
]
|
|
866
884
|
|
|
867
885
|
return intercept, se_intercept, rse_intercept, r2, 'mswd', [a, b, c], 'se', \
|
|
868
886
|
lambda x: [_pow_func(i, a, b, c) for i in x], m_ssresid
|
|
869
887
|
|
|
870
888
|
|
|
871
889
|
def exponential(a0: list, a1: list):
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
890
|
+
try:
|
|
891
|
+
k = _exponential(a0, a1, newton_minimize_1d)
|
|
892
|
+
if k[2] > 100:
|
|
893
|
+
raise ValueError
|
|
894
|
+
if abs(k[0] - min(a0)) > 5 * (max(a0) - min(a0)):
|
|
895
|
+
raise ValueError
|
|
896
|
+
except Exception as e:
|
|
897
|
+
print(f"newton_minimize_1d failed, using grad minimize")
|
|
898
|
+
k = _exponential(a0, a1, grad_minimize)
|
|
899
|
+
return k
|
|
877
900
|
|
|
878
|
-
def _exp_func(x, a, b, c):
|
|
879
|
-
return a * b ** x + c
|
|
880
901
|
|
|
881
|
-
|
|
882
|
-
a, b, c = params
|
|
883
|
-
return [_exp_func(xi, a, b, c) - yi for xi, yi in zip(a1, a0)]
|
|
902
|
+
def _exponential(a0, a1, method):
|
|
884
903
|
|
|
885
|
-
|
|
886
|
-
|
|
904
|
+
X = np.array(a1)
|
|
905
|
+
Y = np.array(a0)
|
|
906
|
+
y = np.array([a0]).transpose()
|
|
887
907
|
|
|
888
|
-
def
|
|
889
|
-
|
|
890
|
-
|
|
908
|
+
def _exp_func(xi, a, b, c):
|
|
909
|
+
return a * np.exp(b * xi) + c
|
|
910
|
+
|
|
911
|
+
@np.vectorize
|
|
912
|
+
def _get_s(b):
|
|
913
|
+
x = np.concatenate(([np.ones(len(a1))], [np.exp(b * np.array(a1))]), axis=0).transpose()
|
|
914
|
+
try:
|
|
915
|
+
inv_xtx = np.linalg.inv(np.matmul(x.transpose(), x))
|
|
916
|
+
except np.linalg.LinAlgError:
|
|
917
|
+
raise np.linalg.LinAlgError(f"The determinant of the given matrix must not be zero ")
|
|
918
|
+
beta = np.matmul(inv_xtx, np.matmul(x.transpose(), y))
|
|
919
|
+
c, a = beta.flatten()
|
|
920
|
+
reg_y = _exp_func(X, a, b, c)
|
|
921
|
+
resid = (reg_y - Y) ** 2
|
|
922
|
+
ssresid = sum(resid)
|
|
923
|
+
return ssresid
|
|
924
|
+
|
|
925
|
+
# 1阶
|
|
926
|
+
ini_f1 = linest(Y, X)
|
|
927
|
+
y_range = max(Y) - min(Y)
|
|
928
|
+
ini_b = ini_f1[5][1] / max(y_range, 1e-12)
|
|
929
|
+
# 2阶
|
|
930
|
+
ini_f2 = quadratic(Y, X)
|
|
931
|
+
ini_b *= np.sign(ini_f1[5][1]) * np.sign(ini_f2[5][2])
|
|
932
|
+
|
|
933
|
+
b, count = method(_get_s, ini_b)
|
|
934
|
+
|
|
935
|
+
x = np.concatenate(([np.ones(len(a1))], [np.exp(b * np.array(a1))]), axis=0).transpose()
|
|
936
|
+
|
|
937
|
+
m, n = x.shape # number of data, number of unknown x
|
|
938
|
+
try:
|
|
939
|
+
inv_xtx = np.linalg.inv(np.matmul(x.transpose(), x))
|
|
940
|
+
except np.linalg.LinAlgError:
|
|
941
|
+
raise np.linalg.LinAlgError(f"The determinant of the given matrix must not be zero ")
|
|
942
|
+
beta = np.matmul(inv_xtx, np.matmul(x.transpose(), y))
|
|
943
|
+
estimate_y = np.matmul(x, beta)
|
|
944
|
+
resid = (estimate_y - y) ** 2
|
|
945
|
+
reg = (estimate_y - np.mean(y)) ** 2
|
|
946
|
+
ssresid = resid.sum() # 残差平方和
|
|
947
|
+
ssreg = reg.sum() # 回归平方和
|
|
948
|
+
sstotal = ((y - np.mean(y)) ** 2).sum()
|
|
949
|
+
r2 = ssreg / sstotal if sstotal != 0 else 1
|
|
891
950
|
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
951
|
+
df = m - n
|
|
952
|
+
m_ssresid = ssresid / df # 均方残差,与加权平均中的MSWD对应
|
|
953
|
+
cov_beta = m_ssresid * inv_xtx
|
|
895
954
|
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
step = 0.01
|
|
901
|
-
while count < 100:
|
|
902
|
-
a, b, c = _get_ac(b)
|
|
903
|
-
s = _sum_squared_error([a, b, c])
|
|
904
|
-
b_left, b_right = b - step * b, b + step * b
|
|
905
|
-
s_left = _sum_squared_error(_get_ac(b_left))
|
|
906
|
-
s_right = _sum_squared_error(_get_ac(b_right))
|
|
907
|
-
if s_left > s > s_right:
|
|
908
|
-
b = b_right
|
|
909
|
-
continue
|
|
910
|
-
elif s_left < s < s_right:
|
|
911
|
-
b = b_left
|
|
912
|
-
continue
|
|
913
|
-
elif s_left < s_right:
|
|
914
|
-
b = (b + b_left) / 2
|
|
915
|
-
else:
|
|
916
|
-
b = (b + b_right) / 2
|
|
917
|
-
count += 1
|
|
918
|
-
step = step * 0.5
|
|
919
|
-
if step < 0.000001:
|
|
920
|
-
break
|
|
955
|
+
sc, sa = np.diagonal(cov_beta) ** .5
|
|
956
|
+
c, a = beta.flatten()
|
|
957
|
+
intercept = a + c
|
|
958
|
+
se_intercept = pow(sa ** 2 + sc ** 2 + 2 * cov_beta[0][1] , 0.5)
|
|
921
959
|
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
except IndexError:
|
|
929
|
-
raise IndexError
|
|
960
|
+
exp_beta = [a, b, c]
|
|
961
|
+
exp_cov_beta = [
|
|
962
|
+
[cov_beta[1][1], 0, cov_beta[1][0]],
|
|
963
|
+
[0, 0, 0],
|
|
964
|
+
[cov_beta[0][1], 0, cov_beta[0][0]],
|
|
965
|
+
]
|
|
930
966
|
|
|
931
|
-
f =
|
|
932
|
-
a, sea, c, sec = f[5][1], f[6][1], f[0], f[1]
|
|
967
|
+
# print(f"{b = }, {a = }, {c = }, {count = }, {ssresid = }, {r2 = }")
|
|
933
968
|
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
reg = [(i - sum(calculated_y) / len(calculated_y)) ** 2 for i in calculated_y]
|
|
937
|
-
ssresid = sum(resid)
|
|
938
|
-
ssreg = sum(reg)
|
|
939
|
-
sstotal = ssreg + ssresid
|
|
940
|
-
dp = len(a1)
|
|
941
|
-
df = dp - 1
|
|
942
|
-
m_ssresid = ssresid / df
|
|
943
|
-
r2 = ssreg / sstotal if sstotal != 0 else 1
|
|
969
|
+
return intercept, se_intercept, se_intercept / abs(intercept) * 100, r2, m_ssresid, exp_beta, exp_cov_beta, \
|
|
970
|
+
lambda x: [_exp_func(xi, a, b, c) for xi in x], m_ssresid
|
|
944
971
|
|
|
945
|
-
z = [b ** xi for xi in a1]
|
|
946
|
-
intercept = a + c
|
|
947
|
-
se_intercept_1 = np.sqrt(sea ** 2 + sec ** 2)
|
|
948
|
-
# calculate error of intercept
|
|
949
|
-
errfz = pow(sum([i ** 2 for i in z]) / (dp * sum([i ** 2 for i in z]) - sum(z) ** 2), 0.5)
|
|
950
|
-
errfx = pow(sum([i ** 2 for i in a1]) / (dp * sum([i ** 2 for i in a1]) - sum(a1) ** 2), 0.5)
|
|
951
|
-
# seb = errfz * sey = errfz * ssresid / df -> se_intercept = sey * errfx = seb / errfz * errfx
|
|
952
|
-
se_intercept = sec / errfz * errfx
|
|
953
|
-
rse_intercept = se_intercept / intercept * 100
|
|
954
972
|
|
|
955
|
-
|
|
956
|
-
|
|
973
|
+
def newton_minimize_1d(func, x0, h=1e-5, tol=1e-8, max_iter=30):
|
|
974
|
+
x = x0
|
|
975
|
+
for i in range(max_iter):
|
|
976
|
+
fx = func(x)
|
|
977
|
+
if not np.isfinite(fx):
|
|
978
|
+
raise ValueError("Newton Minimize: Function returned non-finite value at x={}".format(x))
|
|
979
|
+
|
|
980
|
+
# 一阶导数(中心差分)
|
|
981
|
+
f_plus = func(x + h)
|
|
982
|
+
f_minus = func(x - h)
|
|
983
|
+
if not (np.isfinite(f_plus) and np.isfinite(f_minus)):
|
|
984
|
+
raise ValueError("Newton Minimize: Non-finite values in derivative computation")
|
|
985
|
+
df = (f_plus - f_minus) / (2 * h)
|
|
986
|
+
d2f = (f_plus - 2 * fx + f_minus) / (h * h)
|
|
987
|
+
|
|
988
|
+
# 牛顿步长
|
|
989
|
+
if abs(d2f) < 1e-12: # 避免除零或平坦区域
|
|
990
|
+
raise ValueError("Newton Minimize: Second derivative too small, stopping.")
|
|
991
|
+
|
|
992
|
+
step = df / d2f
|
|
993
|
+
x_new = x - step
|
|
994
|
+
|
|
995
|
+
if abs(step) < tol:
|
|
996
|
+
x = x_new
|
|
997
|
+
break
|
|
998
|
+
|
|
999
|
+
x = x_new
|
|
1000
|
+
|
|
1001
|
+
if i + 1 == max_iter:
|
|
1002
|
+
raise ValueError("Newton Minimize: Over iteration max_iter={}".format(max_iter))
|
|
1003
|
+
|
|
1004
|
+
return x, i + 1
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
def grad_minimize(func, x, lr=1e-5, tol=1e-8, max_iter=1000):
|
|
1008
|
+
|
|
1009
|
+
for i in range(max_iter):
|
|
1010
|
+
f_plus = func(x + lr)
|
|
1011
|
+
f_minus = func(x - lr)
|
|
1012
|
+
if not (np.isfinite(f_plus) and np.isfinite(f_minus)):
|
|
1013
|
+
raise ValueError("Newton Minimize: Non-finite values in derivative computation")
|
|
1014
|
+
g = (f_plus - f_minus) / (2 * lr)
|
|
1015
|
+
x_new = x - lr * g
|
|
1016
|
+
if abs(func(x_new) - func(x)) < tol:
|
|
1017
|
+
break
|
|
1018
|
+
x = x_new
|
|
1019
|
+
return x, i+1
|
|
957
1020
|
|
|
958
1021
|
|
|
959
1022
|
""" line functions """
|
|
960
1023
|
|
|
961
1024
|
|
|
962
|
-
def
|
|
1025
|
+
def linest_var(beta: list, cov: list, x: float):
|
|
1026
|
+
""" y = b0 * x^0 + b1 * x^1 + ... + bn * x^n
|
|
1027
|
+
Parameters
|
|
1028
|
+
----------
|
|
1029
|
+
|
|
1030
|
+
Returns
|
|
1031
|
+
-------
|
|
1032
|
+
|
|
1033
|
+
"""
|
|
1034
|
+
beta = np.array(beta, dtype=np.float64)
|
|
1035
|
+
cov_matrix = np.array(cov, dtype=np.float64)
|
|
1036
|
+
g = np.array([x ** k for k in range(len(beta))]).reshape(-1, 1)
|
|
1037
|
+
y = np.dot(g.T, beta.reshape(-1, 1))[0, 0]
|
|
1038
|
+
var = np.matmul(np.matmul(g.T, cov_matrix), g)[0, 0]
|
|
1039
|
+
return y, var
|
|
1040
|
+
|
|
1041
|
+
|
|
1042
|
+
def quadratic_var(beta: list, cov: list, x: float):
|
|
1043
|
+
""" y = b0 * x^0 + b1 * x^1 + b2 * x^2
|
|
1044
|
+
Parameters
|
|
1045
|
+
----------
|
|
1046
|
+
beta : coefficients
|
|
1047
|
+
x :
|
|
1048
|
+
|
|
1049
|
+
Returns
|
|
1050
|
+
-------
|
|
1051
|
+
|
|
1052
|
+
"""
|
|
1053
|
+
beta = np.array(beta, dtype=np.float64)
|
|
1054
|
+
cov_matrix = np.array(cov, dtype=np.float64)
|
|
1055
|
+
g = np.array([x ** k for k in range(len(beta))]).reshape(-1, 1)
|
|
1056
|
+
y = np.dot(g.T, beta.reshape(-1, 1))[0, 0]
|
|
1057
|
+
var = np.matmul(np.matmul(g.T, cov_matrix), g)[0, 0]
|
|
1058
|
+
return y, var
|
|
1059
|
+
|
|
1060
|
+
|
|
1061
|
+
def average_var(beta: list, cov: list, x: float):
|
|
963
1062
|
""" y = b0 * x^0 + b1 * x^1 + ... + bn * x^n
|
|
964
1063
|
Parameters
|
|
965
1064
|
----------
|
|
@@ -970,21 +1069,29 @@ def linear_eq(x: list, beta: list):
|
|
|
970
1069
|
-------
|
|
971
1070
|
|
|
972
1071
|
"""
|
|
973
|
-
|
|
1072
|
+
y, = beta
|
|
1073
|
+
var = np.array(cov, dtype=np.float64)[0, 0]
|
|
1074
|
+
return y, var
|
|
974
1075
|
|
|
975
1076
|
|
|
976
|
-
def
|
|
977
|
-
""" y = a *
|
|
1077
|
+
def exponential_var(beta: list, cov: list, x: float):
|
|
1078
|
+
""" y = a * exp(bx) + c
|
|
978
1079
|
Parameters
|
|
979
1080
|
----------
|
|
980
1081
|
beta : coefficients, [a, b, c]
|
|
981
|
-
|
|
1082
|
+
cov : covariance [[], [], []]
|
|
982
1083
|
|
|
983
1084
|
Returns
|
|
984
1085
|
-------
|
|
985
1086
|
|
|
986
1087
|
"""
|
|
987
|
-
|
|
1088
|
+
cov_matrix = np.array(cov)
|
|
1089
|
+
a, b, c = beta
|
|
1090
|
+
k = np.exp(b*x)
|
|
1091
|
+
g = np.array([k, a*x*k, 1]).reshape(-1, 1)
|
|
1092
|
+
y = a * k + c
|
|
1093
|
+
var = np.matmul(np.matmul(g.T, cov_matrix), g)[0, 0]
|
|
1094
|
+
return y, var
|
|
988
1095
|
|
|
989
1096
|
|
|
990
1097
|
def power_eq(x: list, beta: list):
|
|
@@ -493,40 +493,41 @@ def open_full_xls(file_path: str, sample_name: str = ''):
|
|
|
493
493
|
res['Inverse Isochron Table'], rows, [4, 5, 6, 7, 10])
|
|
494
494
|
total_param = arr.partial(
|
|
495
495
|
res['Sample Parameters'], rows, [
|
|
496
|
-
# 1, 2,
|
|
497
|
-
-1, -1, -1, -1, #
|
|
498
|
-
-1, -1, -1, -1, #
|
|
499
|
-
-1, -1, -1, -1, -1, -1, #
|
|
500
|
-
-1, -1, -1, -1, #
|
|
501
|
-
-1, -1, #
|
|
502
|
-
23, 24, -1, -1, -1, -1, #
|
|
503
|
-
-1, -1, #
|
|
504
|
-
22, -1, -1, -1, #
|
|
505
|
-
-1, -1, #
|
|
506
|
-
-1, -1, #
|
|
507
|
-
-1, -1, #
|
|
508
|
-
-1, -1, #
|
|
509
|
-
-1, -1, #
|
|
510
|
-
-1, -1, #
|
|
511
|
-
-1, -1, #
|
|
512
|
-
-1, -1, #
|
|
513
|
-
-1, -1, #
|
|
514
|
-
-1, -1, #
|
|
515
|
-
-1, -1, #
|
|
516
|
-
-1, -1, #
|
|
517
|
-
-1, -1, #
|
|
518
|
-
-1, -1, -1, -1, -1, -1, -1, -1, -1, #
|
|
519
|
-
10, 11, 12, 13, #
|
|
520
|
-
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, #
|
|
521
|
-
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, #
|
|
522
|
-
-1, -1, -1, -1, #
|
|
523
|
-
-1, -1, -1, -1, #
|
|
524
|
-
-1, -1, -1, -1, #
|
|
525
|
-
-1, -1, -1, -1, #
|
|
526
|
-
-1, -1, -1, -1, #
|
|
527
|
-
-1, -1, -1, -1, -1, -1, -1, -1, #
|
|
528
|
-
-1, -1, -1, -1, -1, -1, -1, -1, #
|
|
529
|
-
-1, -1, -1, -1, -1, #
|
|
496
|
+
# 1, 2, -1, # 0-2
|
|
497
|
+
-1, -1, -1, -1, # 3-6
|
|
498
|
+
-1, -1, -1, -1, # 7-10
|
|
499
|
+
-1, -1, -1, -1, -1, -1, # 11-16
|
|
500
|
+
-1, -1, -1, -1, # 17-20
|
|
501
|
+
-1, -1, # 21-22
|
|
502
|
+
23, 24, -1, -1, -1, -1, # 23-28
|
|
503
|
+
-1, -1, # 29-30
|
|
504
|
+
22, -1, -1, -1, # 31-34
|
|
505
|
+
-1, -1, # 35-36
|
|
506
|
+
-1, -1, # 37-38
|
|
507
|
+
-1, -1, # 39-40
|
|
508
|
+
-1, -1, # 41-42
|
|
509
|
+
-1, -1, # 43-44
|
|
510
|
+
-1, -1, # 45-46
|
|
511
|
+
-1, -1, # 47-48
|
|
512
|
+
-1, -1, # 49-50
|
|
513
|
+
-1, -1, # 51-52
|
|
514
|
+
-1, -1, # 53-54
|
|
515
|
+
-1, -1, # 55-56
|
|
516
|
+
-1, -1, # 57-58
|
|
517
|
+
-1, -1, # 59-60
|
|
518
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, # 61-69
|
|
519
|
+
10, 11, 12, 13, # 70-73
|
|
520
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, # 74-85
|
|
521
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, # 86-95
|
|
522
|
+
-1, -1, -1, -1, # 96-99
|
|
523
|
+
-1, -1, -1, -1, # 100-103
|
|
524
|
+
-1, -1, -1, -1, # 104-107
|
|
525
|
+
-1, -1, -1, -1, # 108-111
|
|
526
|
+
-1, -1, -1, -1, # 112-115
|
|
527
|
+
-1, -1, -1, -1, -1, -1, -1, -1, # 116-123
|
|
528
|
+
-1, -1, -1, -1, -1, -1, -1, -1, # 124-131
|
|
529
|
+
-1, -1, -1, -1, -1, # 132-136
|
|
530
|
+
-1, -1, -1, -1, # 137-140
|
|
530
531
|
])
|
|
531
532
|
|
|
532
533
|
month_convert = {'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04', 'May': '05', 'Jun': '06',
|