123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- import numpy as np
- def open_file(path):
- """depends on the format of file we open"""
- freq, re, im = [], [], []
- with open(path) as f:
- for line in f:
- temp = line[:-1].split(' ')
- for i in range(3):
- temp[i] = temp[i].replace(" ", "")
- freq.append(float(temp[0]))
- re.append(float(temp[1]))
- im.append(float(temp[2]))
- return freq, re, im
- def prepare_data(freq, re, im, fl=None):
- """the function takes raw data and gives vectors of eq (8)"""
-
- if fl is None:
- s = abs(np.array(re) + np.array(im) * 1j)
-
- fl = freq[list(abs(s)).index(min(abs(s)))]
-
- f0 = fl
-
- e1, e2, e3, gamma, p = [], [], [], [], []
- for i in range(0, len(freq)):
-
- t = 2 * (freq[i] - fl) / f0
- g = re[i] + im[i] * 1j
- e1.append(t)
- e2.append(1)
- e3.append(-t * g)
- gamma.append(g)
- p.append(1 / (1 + t ** 2 * (1 + re[i] ** 2 + im[i] ** 2)))
- data = np.array([e1, e2, e3, gamma, p], dtype=np.cdouble)
- return data, fl
- def solution(data):
- """ takes projections of equation (8) on vectors e1, e2, e3 and solves the equations.
- It is also gives matrix of equation"""
- c = []
- b = []
- for i in range(3):
- c1 = np.vdot(data[i], data[4] * data[0])
- c2 = np.vdot(data[i], data[4] * data[1])
- c3 = np.vdot(data[i], data[4] * data[2])
- c.append([c1, c2, c3])
- b.append(np.vdot(data[i], data[4] * data[3]))
- c = np.array(c)
- a = np.linalg.solve(c, b)
- d = np.linalg.inv(c)
- return a, c, d
- def q_factor(a):
- """calculation of result"""
- Ql = a[2].imag
- diam = abs(a[1] - a[0] / a[2])
- k = 1 / (2 / diam - 1)
- Q = Ql * (1 + k)
- return Ql, diam, k, Q
- def recalculation_of_data(data, a, c, d, error=False):
- """preparation data for the next iteration of solving system"""
-
- eps = np.array(a[0] * data[0] + a[1] * data[1] - a[2] * data[0] * data[3] - data[3], dtype=complex)
-
- S2 = np.dot(abs(data[4]), abs(eps) * abs(eps))
- sigma2A = []
- temp = c[0][0] * d[0][0] + c[1][1] * d[1][1] + c[2][2] * d[2][2]
- for i in range(3):
- sigma2A.append(d[i][i] * S2 / temp)
- for i in range(len(data[4])):
- data[4][i] = 1 / (
- data[0][i] ** 2 * sigma2A[0] + sigma2A[1] + data[0][i] ** 2 * sigma2A[2] * (abs(data[3][i]) ** 2))
- if error:
- return abs(np.array(sigma2A))
- else:
- return data
- def recalculating(data, a, c, d, n, printing=False):
- for i in range(2, n):
- data = recalculation_of_data(data, a, c, d)
- a, c, d = solution(data)
- Ql, diam, k, Q = q_factor(a)
- sigma2A = recalculation_of_data(data, a, c, d, error=True)
- sigmaQ0, sigmaQl = random_deviation(a, sigma2A, diam, k, Ql)
- if printing:
- print(f"Q = {Q} +- {sigmaQ0}, if i == {i}")
- def random_deviation(a, sigma2A, diam, k, Ql):
- """defines standart deviations of values"""
- sigmaQl = sigma2A[2] ** 0.5
- sigmaDiam = (sigma2A[0] / (abs(a[2]) ** 2) + sigma2A[1] + abs(a[0] / a[2] / a[2]) ** 2 * sigma2A[2]) ** 0.5
- sigmaK = 2 * sigmaDiam / ((2 - diam) ** 2)
- sigmaQ0 = ((1 + k) ** 2 * sigma2A[2] + Ql ** 2 * sigmaK ** 2) ** 0.5
- return sigmaQ0, sigmaQl
- def apply(filename):
- freq, re, im = open_file(filename)
- data = prepare_data(freq, re, im)
- a, c, d = solution(data)
- recalculating(data, a, c, d, 10, printing=True)
- def fl_fitting(freq, re, im):
- """providing an option to find actual fl"""
- data, fl = prepare_data(freq, re, im)
- a, c, d = solution(data)
- Ql, Q, sigmaQ0, sigmaQl = None, None, None, None
-
-
-
-
-
- for x in range(0, 3):
- g_c = (np.conj(a[2]) * a[1] - a[0]) / (np.conj(a[2]) - a[2])
- g_d = a[0] / a[2]
- g_2 = 2 * g_c - g_d
- dt = (a[1] - g_2) / (g_2 * a[2] - a[0])
- fl2 = fl * (1 + np.real(dt) / 2)
- data, fl = prepare_data(freq, re, im, fl2)
- a, c, d = solution(data)
- recalculating(data, a, c, d, 20)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- return Q, sigmaQ0, Ql, sigmaQl, a
|