アナログ回路とフーリエ変換


```Python
# Program Name: integrated_circuit_analysis.py
# Creation Date: 20250612
# Overview: Integrates RC response, Fourier series, geometric visualization, ADC quantization, MOS characteristics, CMOS inverter VTC
# Usage: Run directly with Python3 + matplotlib + numpy

import numpy as np
import matplotlib.pyplot as plt

# ==================== ① RC回路：Bode線図・ステップ応答 ====================
R = 1e3
C = 100e-12
tau = R * C
w = np.logspace(3, 10, 1000)
H = 1 / (1 + 1j * w * R * C)
mag_db = 20 * np.log10(np.abs(H))
w_3db = 1 / tau
t = np.linspace(0, 10 * tau, 1000)
v_out_step = 1 - np.exp(-t / tau)
t_90 = -tau * np.log(0.1)

# ==================== ② フーリエ級数：矩形波 ====================
T = 2 * np.pi
t_rect = np.linspace(0, T, 1000).reshape(1, -1)
n_vec = np.arange(1, 20, 2).reshape(-1, 1)
rect_terms = (2 / (n_vec * np.pi)) * np.sin(n_vec * t_rect)
rect_wave = 0.5 + rect_terms.sum(axis=0)

# ==================== ③ 図形：90〜180°除去円 ====================
theta = np.linspace(0, 2 * np.pi, 500)
x_circle = np.cos(theta)
y_circle = np.sin(theta)
mask = ~((np.degrees(theta) >= 90) & (np.degrees(theta) <= 180))
x_arc = x_circle[mask]
y_arc = y_circle[mask]

# ==================== ④ ADC：Sine波とRamp波への4bit量子化 ====================
adc_bits = 4
adc_levels = 2 ** adc_bits
adc_min, adc_max = -1.0, 1.0

t_adc = np.linspace(0, 2 * np.pi, 500)
sine_in = np.sin(t_adc)
sine_adc = np.clip(((sine_in - adc_min) / (adc_max - adc_min)) * adc_levels, 0, adc_levels - 1)
sine_adc_norm = sine_adc / (adc_levels - 1)

ramp_in = np.linspace(-1.5, 1.5, 1000)
ramp_adc = np.clip(((ramp_in - adc_min) / (adc_max - adc_min)) * adc_levels, 0, adc_levels - 1)
ramp_adc_norm = ramp_adc / (adc_levels - 1)

# ==================== ⑤ nMOSのId-Vds特性（Level-1モデル） ====================
Vdd = 3.3
Vgs_list = [0.6, 0.7, 0.8, 0.9]
Vds = np.linspace(0, Vdd, 500)
kn = 200e-6
Vth_n = 0.6

def id_nmos(Vgs, Vds):
    Vov = Vgs - Vth_n
    return np.where(Vds < Vov, kn * (2 * Vov * Vds - Vds**2), kn * Vov**2)

# ==================== ⑥ CMOSインバータ：ロジスティック関数モデル ====================
Vin = np.linspace(0, Vdd, 1000)
Vth = Vdd / 2
k = 10
Vout_cmos = Vdd / (1 + np.exp(k * (Vin - Vth)))

# ==================== プロット ====================
fig, axs = plt.subplots(6, 1, figsize=(10, 32))

# ① RC応答
axs[0].semilogx(w, mag_db)
axs[0].axhline(-3, color='r', linestyle='--')
axs[0].axvline(w_3db, color='g', linestyle='--')
axs[0].set_title('① RC Circuit Frequency Response')
axs[0].set_xlabel('ω [rad/s]')
axs[0].set_ylabel('Gain [dB]')
axs[0].grid()

axs[1].plot(t, v_out_step)
axs[1].axhline(0.9, color='r', linestyle='--')
axs[1].axvline(t_90, color='g', linestyle='--')
axs[1].set_title('① RC Circuit Step Response')
axs[1].set_xlabel('Time [s]')
axs[1].set_ylabel('V_out(t)')
axs[1].grid()

# ② フーリエ矩形波
axs[2].plot(t_rect.flatten(), rect_wave)
axs[2].set_title('② Fourier Series: Square Wave')
axs[2].set_xlabel('Time')
axs[2].set_ylabel('Amplitude')
axs[2].grid()

# ③ 円の90〜180°除去
axs[3].plot(x_arc, y_arc, color='purple')
axs[3].set_aspect('equal')
axs[3].set_title('③ Circle Missing 90°–180° Sector')
axs[3].grid()

# ④ ADC（Sine波）
axs[4].plot(t_adc, sine_in, label='Input: Sine')
axs[4].step(t_adc, sine_adc_norm, where='mid', label='ADC Output (4bit)')
axs[4].set_title('④ 4bit ADC on Sine Input')
axs[4].set_xlabel('Time')
axs[4].set_ylabel('Normalized Output')
axs[4].legend()
axs[4].grid()

# ⑥ CMOSインバータ
axs[5].plot(Vin, Vout_cmos, label='CMOS VTC (Logistic)')
axs[5].axvline(Vth, color='red', linestyle='--', label=f'Vth = {Vth:.2f} V')
axs[5].set_title('⑥ CMOS Inverter VTC (Logistic Function)')
axs[5].set_xlabel('Vin [V]')
axs[5].set_ylabel('Vout [V]')
axs[5].legend()
axs[5].grid()

plt.tight_layout()
plt.show()

# ⑤ nMOS特性（別図）
plt.figure(figsize=(8, 5))
for Vgs in Vgs_list:
    plt.plot(Vds, id_nmos(Vgs, Vds), label=f"Vgs = {Vgs:.1f}V")
plt.title("⑤ nMOS Id-Vds Characteristics")
plt.xlabel("Vds [V]")
plt.ylabel("Id [A]")
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()

# ④ ADC（Ramp波：別図）
plt.figure(figsize=(10, 4))
plt.step(ramp_in, ramp_adc_norm, where='mid', color='orange')
plt.title("④ 4bit ADC on Ramp Input")
plt.xlabel("Input Voltage [V]")
plt.ylabel("Normalized Output")
plt.grid(True)
plt.tight_layout()
plt.show()

```