import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit

# 1 график
# Данные эксперимента для прямых ВАХ диодов VD1 и VD2
vd1_direct_voltage = [0.382, 0.407, 0.471, 0.501, 0.534, 0.554, 0.580, 0.598, 0.617]
vd2_direct_voltage = [0.046, 0.065, 0.123, 0.152, 0.184, 0.203, 0.227, 0.244, 0.261]
vd_direct_current = [50, 100, 500, 1000, 2000, 3000, 5000, 7000, 10000]  # Токи в µA

# Переводим токи из µA в мА
vd_direct_current = [i / 1000 for i in vd_direct_current]

# Преобразуем данные в numpy массивы
vd1_voltage = np.array(vd1_direct_voltage)
vd2_voltage = np.array(vd2_direct_voltage)
vd_current = np.array(vd_direct_current)

# Определяем экспоненциальную функцию для аппроксимации
def exp_func(V, A, B):
    return A * np.exp(B * V)

# Аппроксимация для VD1
popt_vd1, pcov_vd1 = curve_fit(exp_func, vd1_voltage, vd_current, p0=(1e-9, 40))
# Аппроксимация для VD2
popt_vd2, pcov_vd2 = curve_fit(exp_func, vd2_voltage, vd_current, p0=(1e-9, 40))

# Генерируем данные для аппроксимационных кривых
vd1_voltage_fit = np.linspace(min(vd1_voltage), max(vd1_voltage), 100)
vd2_voltage_fit = np.linspace(min(vd2_voltage), max(vd2_voltage), 100)
vd1_current_fit = exp_func(vd1_voltage_fit, *popt_vd1)
vd2_current_fit = exp_func(vd2_voltage_fit, *popt_vd2)

# Построение прямых ВАХ для обоих диодов с аппроксимацией
plt.figure(figsize=(10, 6))
plt.plot(vd1_voltage, vd_current, 'o', label="VD1 КД105В - экспериментальные данные")
plt.plot(vd1_voltage_fit, vd1_current_fit, '-', label="VD1 КД105В - аппроксимация")
plt.plot(vd2_voltage, vd_current, 'o', label="VD2 Д7Б - экспериментальные данные")
plt.plot(vd2_voltage_fit, vd2_current_fit, '-', label="VD2 Д7Б - аппроксимация")
plt.title('Прямые ВАХ диодов')
plt.xlabel('Напряжение (В)')
plt.ylabel('Ток (мА)')
plt.grid(True)
plt.legend()
plt.savefig('direct_vi_characteristics.png')
plt.show()

# 2 график
# Данные эксперимента для обратных ВАХ диодов VD1 и VD2
vd1_reverse_voltage_raw = [0.1, 0.2, 0.5, 1, 2, 3, 5, 7, 10]
vd1_reverse_current_raw = [-0.01, -0.02, -0.04, -0.05, -0.06, -0.07, -0.08, -0.08, -0.09]  # Токи в µA

vd2_reverse_voltage_raw = [0.1, 0.2, 0.5, 1, 2, 3, 5, 7, 10]
vd2_reverse_current_raw = [-7.86, -12.54, -13.64, -13.79, -13.95, -14.07, -14.26, -14.4, -14.48]  # Токи в µA

# Преобразуем напряжения и токи в отрицательные значения для третьей четверти
vd1_reverse_voltage = -np.array(vd1_reverse_voltage_raw)
vd1_reverse_current = np.array(vd1_reverse_current_raw)

vd2_reverse_voltage = -np.array(vd2_reverse_voltage_raw)
vd2_reverse_current = np.array(vd2_reverse_current_raw)

# Определяем функцию для аппроксимации с использованием абсолютного значения напряжения
def power_law_func(V, a, b, c):
    return a * np.power(np.abs(V), b) + c

# Аппроксимация для VD1
popt_vd1_rev, pcov_vd1_rev = curve_fit(power_law_func, vd1_reverse_voltage, vd1_reverse_current, maxfev=10000)
vd1_voltage_fit_linspace = np.linspace(min(vd1_reverse_voltage), max(vd1_reverse_voltage), 100)
vd1_current_fit_curve = power_law_func(vd1_voltage_fit_linspace, *popt_vd1_rev)

# Аппроксимация для VD2
popt_vd2_rev, pcov_vd2_rev = curve_fit(power_law_func, vd2_reverse_voltage, vd2_reverse_current, maxfev=10000)
vd2_voltage_fit_linspace = np.linspace(min(vd2_reverse_voltage), max(vd2_reverse_voltage), 100)
vd2_current_fit_curve = power_law_func(vd2_voltage_fit_linspace, *popt_vd2_rev)

# Построение обратных ВАХ для VD1 с аппроксимацией
plt.figure(figsize=(7, 6))
plt.plot(vd1_reverse_voltage, vd1_reverse_current, 'o', label="VD1 КД105В - экспериментальные данные", color='blue')
plt.plot(vd1_voltage_fit_linspace, vd1_current_fit_curve, '-', label="VD1 КД105В - аппроксимация", color='blue')
plt.title('Обратные ВАХ VD1 КД105В (3-я четверть)')
plt.xlabel('Напряжение (В)')
plt.ylabel('Ток (µА)')
plt.grid(True)
plt.legend()
plt.savefig('reverse_vi_characteristics_split_vd1.png')
plt.show()

# Построение обратных ВАХ для VD2 с аппроксимацией
plt.figure(figsize=(7, 6))
plt.plot(vd2_reverse_voltage, vd2_reverse_current, 'o', label="VD2 Д7Б - экспериментальные данные", color='orange')
plt.plot(vd2_voltage_fit_linspace, vd2_current_fit_curve, '-', label="VD2 Д7Б - аппроксимация", color='orange')
plt.title('Обратные ВАХ VD2 Д7Б (3-я четверть)')
plt.xlabel('Напряжение (В)')
plt.ylabel('Ток (µА)')
plt.grid(True)
plt.legend()
plt.savefig('reverse_vi_characteristics_split_vd2.png')
plt.show()

# Построение обратных ВАХ для обоих диодов с аппроксимацией
plt.figure(figsize=(10, 6))
plt.plot(vd1_reverse_voltage, vd1_reverse_current, 'o', label="VD1 КД105В - экспериментальные данные")
plt.plot(vd1_voltage_fit_linspace, vd1_current_fit_curve, '-', label="VD1 КД105В - аппроксимация")
plt.plot(vd2_reverse_voltage, vd2_reverse_current, 'o', label="VD2 Д7Б - экспериментальные данные")
plt.plot(vd2_voltage_fit_linspace, vd2_current_fit_curve, '-', label="VD2 Д7Б - аппроксимация")
plt.title('Обратные ВАХ диодов')
plt.xlabel('Напряжение (В)')
plt.ylabel('Ток (µА)')
plt.grid(True)
plt.legend()
plt.savefig('reverse_vi_characteristics.png')
plt.show()

# 3 график
vd3_extended_voltage_raw = [0.5, 1, 2, 3, 5, 7, 10, 12, 15]
vd3_extended_current_raw = [-2.53, -2.79, -3.08, -3.25, -3.47, -3.62, -3.78, -10, -25]

# Преобразуем напряжения в отрицательные значения для третьей четверти
vd3_extended_voltage = -np.array(vd3_extended_voltage_raw)
vd3_extended_current = np.array(vd3_extended_current_raw)

# Аппроксимация для стабилитрона с использованием абсолютного значения напряжения
def exp_func_vd3(V, a, b, c):
    return a * np.exp(b * np.abs(V)) + c

popt_vd3, pcov_vd3 = curve_fit(exp_func_vd3, vd3_extended_voltage, vd3_extended_current, maxfev=10000)

# Генерируем данные для аппроксимационной кривой
vd3_voltage_fit = np.linspace(min(vd3_extended_voltage), max(vd3_extended_voltage), 200)
vd3_current_fit = exp_func_vd3(vd3_voltage_fit, *popt_vd3)

plt.figure(figsize=(10, 6))
plt.plot(vd3_extended_voltage, vd3_extended_current, 'o', label="VD3 КС139А - экспериментальные данные")
plt.plot(vd3_voltage_fit, vd3_current_fit, '-', label="VD3 КС139А - аппроксимация")
plt.title('Обратная ВАХ стабилитрона VD3 (КС139А)')
plt.xlabel('Напряжение (В)')
plt.ylabel('Ток (мА)')
plt.grid(True)
plt.legend()
plt.savefig('reverse_vi_zener.png')
plt.show()
