・Pythonの高周波用ライブラリ scikit-rfを使う
・Visual C#で数値計算ライブラリ Math.NET numericsを使う(Visual Basic版もあり)
・高周波エンジニアのためのAI・機械学習入門
・JavaScriptの数値計算ライブラリmath.jsを使う
・カシオの高精度計算サイトに投稿した自作式一覧
おまけ
円の弧長,弦長,矢高,半径のどれか2つを与えて残りを計算(改善版)
・Pythonの高周波用ライブラリ scikit-rfを使う
・Visual C#で数値計算ライブラリ Math.NET numericsを使う(Visual Basic版もあり)
・高周波エンジニアのためのAI・機械学習入門
・JavaScriptの数値計算ライブラリmath.jsを使う
・カシオの高精度計算サイトに投稿した自作式一覧
おまけ
円の弧長,弦長,矢高,半径のどれか2つを与えて残りを計算(改善版)
・Pythonの高周波ライブラリscikit-rfがv2.1.0でTouchstone v2.1に対応
https://github.com/scikit-rf/scikit-rf/releases/tag/v2.1.0
・Mini-CircutsがSバンドアップコンバータ製作解説
・6Gフォーラムは10月6日開催
https://www.6g-forum.com/home
・Google Pixel 11分解動画で5Gミリ波AiP確認
Google Pixel 11 Teardown Disassembly Phone Repair Video Review
・LitePointとSTMがUWBでコラボ
前回は特性評価するライブラリを作った。今回は報酬とgymnasium環境を作る。
報酬はこんな感じ。指数関数を使って素子値を更新するのがポイント(Copilot Chatに考えてもらった)。
import numpy as np
def constraint_penalty(value, lower=None, upper=None, weight=1.0, scale=1.0):
"""
value が lower 以上、upper 以下に入るようにペナルティを返す。
制約を満たしていれば0。
"""
penalty = 0.0
if lower is not None and value < lower:
penalty += ((lower - value) / scale) ** 2
if upper is not None and value > upper:
penalty += ((value - upper) / scale) ** 2
return weight * penalty
def score_bpf_analysis(
analysis,
targets,
objective="min_insertion_loss",
):
"""
analysis辞書から報酬を計算する。
targets の例:
targets = {
"insertion_loss_at_f0_dB": {"upper": 2.0, "weight": 10.0, "scale": 1.0},
"passband_ripple_dB_in_design_band": {"upper": 0.5, "weight": 5.0, "scale": 0.2},
"min_return_loss_dB_in_design_band": {"lower": 15.0, "weight": 5.0, "scale": 5.0},
"measured_fbw": {"lower": 0.09, "upper": 0.11, "weight": 3.0, "scale": 0.01},
}
reward は大きいほど良い。
"""
penalty = 0.0
for key, spec in targets.items():
if key not in analysis:
raise KeyError(f"{key} is not found in analysis.")
value = analysis[key]
if not np.isfinite(value):
penalty += 1e6
continue
lower = spec.get("lower", None)
upper = spec.get("upper", None)
weight = spec.get("weight", 1.0)
scale = spec.get("scale", 1.0)
penalty += constraint_penalty(
value=value,
lower=lower,
upper=upper,
weight=weight,
scale=scale,
)
# 目的関数
if objective == "min_insertion_loss":
obj = analysis["insertion_loss_at_f0_dB"]
elif objective == "min_worst_insertion_loss":
obj = analysis["worst_insertion_loss_dB_in_design_band"]
elif objective == "max_return_loss":
obj = -analysis["min_return_loss_dB_in_design_band"]
elif objective == "min_ripple":
obj = analysis["passband_ripple_dB_in_design_band"]
else:
obj = 0.0
if not np.isfinite(obj):
obj = 1e6
reward = -(obj + penalty)
return reward, {
"objective_value": obj,
"penalty": penalty,
"reward": reward,
}
def apply_lc_log_multipliers(
LC_base,
x,
active_rows=None,
):
"""
LC_base の L,C に対して exp(x) の倍率をかける。
x の長さは 2 * n。
x = [x_L1, x_C1, x_L2, x_C2, ..., x_Ln, x_Cn]
active_rows:
最適化対象の行番号。
Noneなら 1〜n 行を対象にする。
"""
LC_new = np.array(LC_base, dtype=float, copy=True)
n = LC_base.shape[0] - 2
if active_rows is None:
active_rows = list(range(1, n + 1))
expected_len = 2 * len(active_rows)
if len(x) != expected_len:
raise ValueError(f"x length must be {expected_len}.")
idx = 0
for row in active_rows:
LC_new[row, 0] = LC_base[row, 0] * np.exp(x[idx])
LC_new[row, 1] = LC_base[row, 1] * np.exp(x[idx + 1])
idx += 2
return LC_new
|
gymnasium環境はこんな感じ。
import numpy as np
import gymnasium as gym
from gymnasium import spaces
import bpf
import bpf_score
class LCBPFOptimizationEnv(gym.Env):
"""
LCラダーBPFのL,C値を強化学習で最適化するGymnasium環境。
事前に synthesize_lc_bpf() で作ったLC_baseを基準に、
L,Cを exp(x) 倍して探索する。
"""
metadata = {"render_modes": []}
def __init__(
self,
n,
LC_base,
Q_values,
f1,
f2,
f0,
fstart,
fstop,
points,
fq=None,
z0=50.0,
first_element="series",
targets=None,
objective="min_insertion_loss",
x_limit=0.7,
action_step=0.08,
max_steps=40,
success_reward=100.0,
name="RL_LC_BPF",
active_rows=None,
):
super().__init__()
self.n = n
self.LC_base = np.array(LC_base, dtype=float, copy=True)
self.Q_values = np.array(Q_values, dtype=object, copy=True)
self.f1 = f1
self.f2 = f2
self.f0 = f0
self.fstart = fstart
self.fstop = fstop
self.points = points
self.fq = f0 if fq is None else fq
self.z0 = z0
self.first_element = first_element
self.targets = targets or {}
self.objective = objective
self.x_limit = float(x_limit)
self.action_step = float(action_step)
self.max_steps = int(max_steps)
self.success_reward = float(success_reward)
self.name = name
if active_rows is None:
self.active_rows = list(range(1, n + 1))
else:
self.active_rows = list(active_rows)
self.dim = 2 * len(self.active_rows)
# 状態: log倍率 x, Sパラメータ評価値, および目標との誤差
self.target_keys = sorted(list(self.targets.keys()))
obs_dim = self.dim + 4 + len(self.target_keys)
low = np.zeros(obs_dim, dtype=np.float32)
high = np.zeros(obs_dim, dtype=np.float32)
low[:self.dim] = -self.x_limit
high[:self.dim] = self.x_limit
low[self.dim:] = 0.0
high[self.dim:] = 10.0
self.observation_space = spaces.Box(
low=low,
high=high,
dtype=np.float32,
)
# 行動: xへの増分。実際の増分は action_step を掛ける
self.action_space = spaces.Box(
low=-1.0,
high=1.0,
shape=(self.dim,),
dtype=np.float32,
)
self.x = None
self.step_count = 0
self.best_reward = -np.inf
self.best_x = None
self.best_analysis = None
self.best_LC = None
def reset(self, seed=None, options=None):
super().reset(seed=seed)
self.x = np.zeros(self.dim, dtype=np.float32)
self.step_count = 0
analysis, LC_current = self._evaluate_current()
reward, details = bpf_score.score_bpf_analysis(
analysis,
targets=self.targets,
objective=self.objective,
)
self.best_reward = reward
self.best_x = self.x.copy()
self.best_analysis = analysis
self.best_LC = LC_current.copy()
obs = self._get_obs(self.x, analysis)
info = {
"analysis": analysis,
"LC_elements": LC_current,
"reward_details": details,
"best_reward": self.best_reward,
}
return obs, info
def step(self, action):
self.step_count += 1
action = np.asarray(action, dtype=np.float32)
action = np.clip(action, -1.0, 1.0)
self.x = self.x + self.action_step * action
self.x = np.clip(self.x, -self.x_limit, self.x_limit)
analysis, LC_current = self._evaluate_current()
reward, details = bpf_score.score_bpf_analysis(
analysis,
targets=self.targets,
objective=self.objective,
)
if reward > self.best_reward:
self.best_reward = reward
self.best_x = self.x.copy()
self.best_analysis = analysis
self.best_LC = LC_current.copy()
success = self._check_success(analysis)
if success:
reward += 10.0 # 制約を満たしているステップではボーナス
terminated = False
truncated = bool(self.step_count >= self.max_steps)
obs = self._get_obs(self.x, analysis)
info = {
"analysis": analysis,
"LC_elements": LC_current,
"reward_details": details,
"success": success,
"best_reward": self.best_reward,
"best_analysis": self.best_analysis,
"best_LC_elements": self.best_LC,
}
return obs, reward, terminated, truncated, info
def _evaluate_current(self):
LC_current = bpf_score.apply_lc_log_multipliers(
self.LC_base,
self.x,
active_rows=self.active_rows,
)
ntwk = bpf.lossy_bpf(
n=self.n,
LC_elements=LC_current,
Q_values=self.Q_values,
fq=self.fq,
fstart=self.fstart,
fstop=self.fstop,
points=self.points,
z0=self.z0,
first_element=self.first_element,
name=self.name,
)
analysis = bpf.evaluate_bpf(
ntwk,
f1=self.f1,
f2=self.f2,
f0=self.f0,
)
return analysis, LC_current
def _check_success(self, analysis):
"""
全制約を満たせば成功。
"""
for key, spec in self.targets.items():
value = analysis[key]
if not np.isfinite(value):
return False
lower = spec.get("lower", None)
upper = spec.get("upper", None)
if lower is not None and value < lower:
return False
if upper is not None and value > upper:
return False
return True
def get_best_result(self):
return {
"best_reward": self.best_reward,
"best_x": self.best_x,
"best_LC_elements": self.best_LC,
"best_analysis": self.best_analysis,
}
def _get_obs(self, x, analysis):
obs_x = np.array(x, dtype=np.float32)
il = analysis.get("insertion_loss_at_f0_dB", 20.0)
rl = analysis.get("min_return_loss_dB_in_design_band", 0.0)
ripple = analysis.get("passband_ripple_dB_in_design_band", 10.0)
fbw = analysis.get("measured_fbw", 0.0)
if not np.isfinite(il): il = 20.0
if not np.isfinite(rl): rl = 0.0
if not np.isfinite(ripple): ripple = 10.0
if not np.isfinite(fbw): fbw = 0.0
metrics = np.array([
np.clip(il, 0.0, 20.0) / 20.0,
np.clip(rl, 0.0, 40.0) / 40.0,
np.clip(ripple, 0.0, 10.0) / 10.0,
np.clip(fbw, 0.0, 0.5) / 0.5
], dtype=np.float32)
errors = []
for key in self.target_keys:
spec = self.targets[key]
val = analysis.get(key, np.nan)
if not np.isfinite(val):
errors.append(10.0)
continue
lower = spec.get("lower", None)
upper = spec.get("upper", None)
scale = spec.get("scale", 1.0)
err = 0.0
if lower is not None and val < lower:
err += (lower - val) / scale
if upper is not None and val > upper:
err += (val - upper) / scale
errors.append(np.clip(err, 0.0, 10.0))
obs_errors = np.array(errors, dtype=np.float32)
return np.concatenate([obs_x, metrics, obs_errors])
|
これを使っていろいろな強化学習のアルゴリズムを試してみよう。
・IEEE Antennas and Propagation Magazine8月号発行
https://ieeexplore.ieee.org/xpl/mostRecentIssue.jsp?punumber=74
・東京農大とロームがテラヘルツ用薄型レンズ開発
・I-PEXの細線同軸ケーブル解説ウェビナー
・NokiaとMediaTekが3GPPベースGNSS RTKでデシメートル精度を達成
その他
Codexでいろいろ遊んでいるが、ちょっと実用的なものを作ろうと思って伝送線路計算ツールを作ってみた。
指示を与えるとすぐできた。
マイクロストリップライン、
ストリップライン、
コプレーナ、
グランド付きコプレーナ。
寸法を入れて特性インピーダンスを計算することも、特性インピーダンスを与えて
電極幅を計算することもできる。寸法単位がmmとμmが選べるようになっているのはいい配慮(指示してないのに)。
IEEEの文献やQucsの文書から計算式は出していた。
せっかくなので公開しようということでこちらがリンク。
https://rf-line-lab-jp.tomohiro-nagai972131.chatgpt.site
次はフィルタとかかな。
Google Gemini 3.7 Flashが発表されて、Antigravityでも使えるようになっていた。
そこでいつもやっているPythonのscikit-rfを使ってTouchstoneフォーマットのSパラメータファイルを読んでdB, 位相, スミスチャート, TDRを表示するGUIアプリを作ってもらおう。
頼むとすぐにImplementation Planができて、
OKだすとすぐにWalkthroughまでできた。
実行すると当然一発で動く。
dB
位相
スミスチャート
TDR
Gemini評判はいまいちだけど、どんどん良くなっていると思う。自分が欲しいようなコードを書くくらいなら十分すぎる性能。
Weekly intelligence for radio-frequency engineering
2026年8月10日〜8月16日(JST)|英語情報を先に要約し、日本語訳とRF視点を併記
今週のRF領域は、次世代無線の「実装と評価」が前面に出た。6G/Wi-Fi 7/8向けチャネルエミュレータ、既存5G網を使うドローンセンシング、60 GHz耐妨害リンクが、AI・センシング・高周波ビームフォーミングを実システムへ落とし込む動きを示す。
デバイス側では、GaNの熱限界を狙うDARPA THREADS、24〜34 GHz宇宙用GaAs PA、9 kHz〜8 GHzのLNA/デジタル減衰器統合品が注目点。受動部品ではsub-GHz統合LTCCフィルタと、330 GHzまで評価された小型導波管フランジが設計密度と高周波実装の課題に応える。
日本語訳: VIAVIは、瞬時帯域幅400 MHz、キャリア周波数最大23.6 GHzに対応するVertex 6.0を発表した。新たに定義される6G波形要件へネイティブ対応し、Wi-Fi 7/8の帯域要件も上回る。FR3 MIMOコンバータとレイトレーシングを組み合わせ、FR3、AI-RAN、ISAC向けRF伝搬デジタルツインとして利用できる。6U筐体は36 RFポート、256デジタルリンク、合計最大1.6 GHz帯域を備える。
RF視点: 6G候補技術の評価がリンク単体から、多ユーザーMIMO、FR3、センシングを含む再現可能なラボ環境へ移っている。最大23.6 GHzなので、FR2/sub-THz全域を直接カバーする装置ではない。
Source: everything RF / VIAVI Solutions日本語訳: BAE SystemsのFAST Labsは、DARPAのデバイススケール放熱技術THREADSプログラムPhase 1を完了し、Phase 2支援を獲得した。材料・プロセス改善により、高性能GaN RF電子デバイスの温度限界克服を目指す。熱管理に成功すれば、RFシステムの到達距離を約3倍にできる可能性があるとしている。
RF視点: GaN PAの性能制約はトランジスタ固有性能だけでなく、接合部からパッケージまでの熱抵抗で決まる。距離3倍はプログラム目標であり、量産デバイスの確定仕様ではない。
Source: everything RF / BAE Systems and DARPA日本語訳: Lockheed Martin、Verizon、NVIDIA、Keysight、ODC、Astris AIは、マイアミ地域でNetSense Airspace Awareness-as-a-Serviceを実証した。既存Verizon 5G周波数、ODCのAI-native RAN、NVIDIA AI Aerial、KeysightのRFシミュレーションを使い、RFの乱れからドローンを検出・識別し、追跡を維持してリアルタイム警報を出した。
RF視点: 通信用RANをセンシング資産として再利用する具体例。実用化ではサイト同期、クラッタ抑圧、反射信号ダイナミックレンジ、通信KPIとの共存が評価点になる。
Source: everything RF / Lockheed Martin partners日本語訳: Perasoは、UAV、自律システム、防衛向けの小型60 GHz通信モジュールPRM2145を発表した。ギガビット級スループット、超低遅延、指向性ビームフォーミングにより、指令リンク、HD映像、ISRデータ、ドローン間通信を狙う。高指向性リンクで混雑、干渉、検出、妨害への耐性向上を目指す。顧客評価は2026年第4四半期を予定。
RF視点: 60 GHzは広帯域と狭ビームを得やすい一方、遮蔽・姿勢変化・雨減衰・ビーム追従が課題。耐妨害性は公表された設計意図であり、第三者評価値は未提示。
Source: everything RF / Peraso日本語訳: Analog Devicesは、24〜34 GHzをカバーする4段構成の宇宙グレードGaAs pHEMT MMIC PA、ADH943ASを発表した。5.5 V電源で利得23 dB、飽和出力34 dBm、OIP3 39 dBm、PAE 23%を提供する。内部50 Ω整合と検波出力により、実装と出力監視を簡素化する。
RF視点: Ka-band SATCOM/マイクロ波無線で使いやすい一チップPA。GaNではなくGaAsで、線形性・周波数範囲・宇宙スクリーニングを重視した構成。
Source: everything RF / Analog Devices日本語訳: Mercury Systemsは、LNA、バイパス経路、6 bitデジタル・ステップ・アッテネータを4 mm QFNに統合したAM1265を発表した。9 kHz〜8 GHzで動作し、LNAは利得20 dB/NF 2 dB、バイパス損失1.4 dB、減衰量31.5 dBを0.5 dB刻みで設定できる。ディスクリート構成比でRF基板面積を最大75%削減できるとしている。
RF視点: 50 dB超の動的ゲイン制御を一部品で行え、広帯域SDR、EW、レーダー、計測器の受信ダイナミックレンジ設計を簡素化する。
Source: everything RF / Mercury Systems日本語訳: Bournsは、770〜928 MHzをカバーする平衡型LTCCバンドパスフィルタFBD1608N080D6を発表した。1.6 × 0.8 × 0.6 mmのモノリシック部品に、フィルタ、バラン変換、インピーダンス整合を統合し、sub-GHz低消費電力IoTのRFフロントエンドを小型化する。正規販売網で供給中。
RF視点: SAW/BAWではなくLTCC受動統合品。部品点数と配線ばらつきを減らせる一方、アンテナや無線ICごとの最終整合評価は必要。
Source: everything RF / Bourns日本語訳: NPLとFlann Microwaveは、小型矩形導波管インターコネクトFSM-45の検証でARFTG賞を受賞した。mmWave/sub-THzでは、従来のIEEE標準インターフェースが導波管開口に対して過大になる。NPLが330 GHzまで測定した結果、小型化したFSM-45は110 GHz超で基準となる現行IEEEフランジと同等以上の電気性能を示した。
RF視点: 高周波ではフランジ寸法、位置合わせ、接触再現性がシステム損失を左右する。sub-THz計測器、6G研究装置、コンパクトな導波管モジュールの実装密度向上につながる。
Source: everything RF / NPL and Flann Microwave日本語訳: u-bloxはM10 GNSSプラットフォーム向けLow Energy Accurate Positioning(LEAP)を発表した。見通しの良い衛星信号を優先し、弱い信号、低仰角信号、マルチパス影響信号を避け、必要に応じて外付けLNAも制御する。測位精度を維持しながらGNSS消費電力を最大50%削減し、0.5 Hz更新では約5 mWまで下げられるとしている。
RF視点: スマートウォッチやトラッカーでは、受信信号を増幅し続ける設計から、測位寄与度に応じてRFチェーンを動的制御する設計へ進む。50%はu-blox公表値で、実機効果はアンテナと環境に依存する。
Source: everything RF / u-blox日本語訳: AIRS-LaaSは、LoS確率、SINR、センシング信頼度、幾何、移動リスク、資源コストで空中/地上アンカーとビームの組を順位付けし、測位前に必要最小限だけを有効化する。測位精度、通信性能、パイロット負荷、電力の両立を狙う。
Source: arXiv:2608.10571日本語訳: 複数基地局と超大規模アンテナアレイを用いるTHz OFDMバイスタティック協調ISACで、センシング対象が盗聴者にもなり得る条件を扱う。アナログビームフォーミング、デジタルプリコーディング、真時間遅延、センシング共分散を共同最適化する。
Source: arXiv:2608.10467いずれも査読前プレプリントであり、標準仕様や量産性能を示すものではありません。
AANI-CH-0212は12 × 4 × 1.6 mm、平均効率65.9%、ピーク利得2.2 dBi。17 × 15 mmのグランドクリアランスで、LoRa、Wi-SUN、Sigfox機器を狙う。
Source: Microwave Journal / Abracon10 dB/20 dB結合の2モデルを追加。平均20 W、ピーク3 kWに対応し、6G、5G NR、Wi-Fi 6/6E、SATCOM、ビームフォーミング計測を対象とする。
Source: everything RF / KRYTARIEEE 802.15.4 SUN-OFDMの信号解析と生成をSpike/VSGへ追加。スマートメータ、産業オートメーション、ユーティリティ網の干渉解析と性能検証向け。
Source: everything RF / Signal Hound知財、顧客関係、人員を含むセルラーモジュール事業をCompalが取得予定。SemtechはデータセンターとLoRa接続へ資源を集中する。完了はSemtech FY2027第4四半期の見込み。
Source: everything RF / Semtech日本語訳: iFixitの8月13日分解では、Galaxy Z Fold8のIP48は耐水性を持つ一方、微細な粉塵を防げないことが確認された。UV反応粒子がヒンジへ入り、異音と開閉不良が発生したが、密閉された電池とメイン基板は比較的きれいだった。チタン補強ディスプレイ、合計18.68 Whの二つのシリコンカーボン電池、独立交換可能なUSB-Cポートも確認。ヒンジ/内側画面の修理は難しく、暫定修理容易性は4/10。
RF視点: 本分解の主題は修理性とヒンジ耐塵性で、RFフロントエンドのチップ同定ではない。ただし、薄型折りたたみ筐体でアンテナ、無線充電コイル、熱拡散、二分割バッテリ、シールド基板を共存させる実装制約を観察できる。
Samsung Galaxy Z Fold 8をiFixitが分解していた。Chip IDはまだ(やるのかな?)。
5Gミリ波AiPを探してみる。ここかな?
CTスキャンで確認。当たり。5つのパッチアンテナが見える。
別角度から。コネクタも見えた。
一番最初の予告編では恐竜もちらっとしか映らないので何の映画?と思っていた。もう恐竜が出るのは予告でもわかる。
なぜこの時代設定にしたのかはわからなかったが、ことあるごとに時代がわかるもの(CMだったり、曲だったり、スポーツ選手だったり)が映るのが面白い。なのでスマホもないし、カメラもポラロイド。
背景の説明がテレビで話しているNASA、天文がすきな長女がカール・セーガン、コスモスを語るのみ、というのがかえってすがすがしい。
最近の映画ではブラックホールの描写が実際のものに近くなっているが、この作品のあれはもう全然というのもすがすがしい。
そういう細かいことは置いておいてとにかく普通の人たちが普通の1982年のアメリカの街並みで恐竜に襲われ、殺されるのが新しい。
恐竜もジュラシックパークと変えてきていて、羽毛があるやつとか、また本家では絶対やらない(できない)行動を2つしていたので笑った。
でもジュラシックパークのオマージュっぽいシーンは結構あった気がする。
そしてとにかくアン・ハサウェイが走って闘いまくるのが新鮮で面白かった。ユアン・マクレガーもだめな夫だがやるときはやる感じで、途中でえ?と思った。これどうやって助かるのか?と思っていたら…なるほど最初の方のが伏線になっていた。タイトルもでないな、と思っていたらそういう…
でもそれをやってしまうとパラドクスが…なんて思ってはいけないんだろう。そういう話ではないという。
・Google Pixel 11シリーズ発表・5Gミリ波対応は日本ではPixel 11 Pro Foldのみ。USモデルは無印11も対応
https://store.google.com/jp/product/pixel_11_pro_fold_specs?hl=ja&srsltid=AfmBOoo8LJmeMmlvbI774W1rjK0aJ2viI5MdZdhv9pg7-26CnvT7iaxB
・Microwave JournalはEuMW特集
https://www.microwavejournal.com/publications/1
・ミニサーキットの車載部品テストアプリケーションノート
・ローデシュワルツのミリ波スキャナがタイの空港に設置
気温、日経平均とやってきて、今回は正解があるものを試そうということで一番簡単なロジスティック写像
x(n+1) = a * x(n) * (1 - x(n))
をやってみる。
コードはこちら。
import torch
import numpy as np
import timesfm
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'Noto Sans CJK JP'
torch.set_float32_matmul_precision("high")
model = timesfm.TimesFM_2p5_200M_torch.from_pretrained("google/timesfm-2.5-200m-pytorch")
n = 1000
npred = 100
x0 = 0.1
a = 4.0
t = np.arange(n)
x = np.zeros(n)
x[0] = x0
for i in range(1, n):
x[i] = a * x[i-1] * (1 - x[i-1])
ttrain = t[:(n-npred)]
ttest = t[(n-npred):]
xtrain = x[:(n-npred)]
xtest = x[(n-npred):]
model.compile(
timesfm.ForecastConfig(
max_context=1024,
max_horizon=256,
normalize_inputs=True,
use_continuous_quantile_head=True,
force_flip_invariance=True,
infer_is_positive=True,
fix_quantile_crossing=True,
)
)
point_forecast, quantile_forecast = model.forecast(
horizon=npred,
inputs=[
xtrain
],
)
fig = plt.figure(figsize=(10, 6))
plt.figure(figsize=(10, 6))
plt.plot(ttest, xtest, label="真値")
plt.plot(ttest, quantile_forecast[0, :, 0], label="予測値")
plt.fill_between(ttest, quantile_forecast[0, :, 1], quantile_forecast[0, :, 9], alpha=0.2, label="10-90 パーセンタイル")
plt.legend()
plt.xlabel("n")
plt.ylabel("x_n")
plt.title(f"ロジスティック写像の予測 a={a}")
|
まずは3周期に落ちるパラメータ(a=3.8285)でやってみる。
なるほどちゃんと予測しているな。次は強いカオス状態(a=4)でやってみる。
全然予測できてないな(そりゃそうだ)。ある程度規則的な動きをするものなら基盤モデルでも予測はできそう。
東野圭吾さんがお亡くなりになってすぐに出たガリレオシリーズ遺作でこれは読まねば…と思って一気に読む。
これは遺作にふさわしい作品だった。
あらすじは「内海薫が刺された。
犯人は70歳ほどの老人。飛び降り自殺を図るも失敗し、
取り調べには黙秘を貫く。
やがて内海に恨みを抱く若い娘が捜査線上に浮かぶが、
老人との関係は不明。それどころか、内海への本当の復讐はこれからだった。
彼女が迫った「究極の選択」とは一体――。
一方、湯川と草薙は、老人の“ある持ち物”を手掛かりに、
「忘れてはいけない謎」の扉を開く。 」
第一部で出たある人物の名前を湯川は知っていたようだが、草薙にはわからない。それをたどっていくうちに…あれ?これもしかしてあの件?マジか?となったら本当にそうだった。なるほど最後の謎だ。これを描かれるということは東野さん、自分の死期がわかっていたのかもしれない。
深く振り返るような作品でした。ただ科学的要素がほぼない(一個だけ最後に出てくる)のはちょっと残念。
Meta Muse Glimmer 30Bが使えるようになっていてGGUFも使える。
https://huggingface.co/meta-models/Muse-Glimmer-30B-GGUF
ということでいつもやっている電子レンジの動作原理と隕石の大気圏突入について聞いてみよう。
どちらも正しく答えられている上に、とても丁寧な説明で好感が持てる。
ーーーー
問:電子レンジの動作原理となぜ2.45GHzが使われているかを教えてください。特に水分子の共振周波数とも関連づけて説明してください。
答え:
電子レンジの加熱は 共鳴吸収ではなく誘電加熱 です。2.45GHzが選ばれているのは、水分子の「ピタリの共鳴周波数」だから、というより実用上の最適解だからです。
マグネトロンでマイクロ波を作る
マグネトロンという真空管で2.45GHz、波長約12.2cmの電磁波を出力します。出力は数百W~1kW程度です。
空洞共振器で食品を照射する
電子レンジ内部は金属の箱=共振空洞です。回転するターンテーブルとスターラーが電場分布を攪拌し、食品全体にマイクロ波が当たるようにしています。
水分子の双極子が回転して摩擦熱になる
水分子は電気的なプラス・マイナスを別々に持つ双極子で、永久双極子モーメントが1.85Dあります。
マイクロ波の電界が2.45×10^9回/秒で向きを変えると、水分子はその電界に追従して回転しようとします。
分子は電界に少し遅れて向きを変えるため、分子同士の衝突でその遅れが熱に変わります。これが誘電損失、言い換えれば回転摩擦による発熱です。
発熱量は誘電率の虚部 ε''、つまり損失正接に比例します。 P ∝ 2π f ε0 ε'' E^2
食品中の水が多く、ε''が大きいほどよく温まります。油や砂糖は水よりε''が小さいので温まりにくい、金属は反射、ガラス・陶器はほぼ透過する、という違いになります。
1. 水の吸収帯と浸透深さのバランス
水の誘電緩和はデバイ緩和で、室温では緩和周波数が約18GHz付近にあります。吸収スペクトルは広く、1GHz~数十GHzで強く吸収されます。
2.45GHzは吸収が十分強く、かつ食品への浸透深さが1~2cm程度と適度です。
周波数が高すぎると浸透深さが数mmになり表面だけが焦げる。低すぎると浸透は深いがマグネトロンの作りが大型になり、発熱効率が下がります。
2. ISMバンドの割り当て
2.45~2.50GHzは国際的に産業・科学・医療用 ISMバンドとして割り当てられています。通信に使われないため干渉を受けにくく、世界中で使える周波数です。
3. マグネトロンの技術的都合
2.45GHzはマグネトロンで効率よく、比較的小型に高出力が得られる周波数でした。1940年代にパーシー・スペンサーがレーダーのマグネトロンを調べていて偶然チョコレートが溶けたことから実用化され、その設計がそのまま継承されています。
「2.45GHzは水分子の共鳴周波数」と言われることがありますが厳密には違います。
要するに、2.45GHzは「水分子とピタリ共鳴する」周波数ではなく、「水がよく吸収し、食品に適度に浸透し、装置も作りやすい」周波数として国際的に標準化されたもの、というのが正確な理解です。
問:隕石が大気圏に突入すると燃えてしまいますが、その原理を教えてください。
答え:
隕石が「燃える」のは摩擦熱だけではなく、主に運動エネルギーが熱エネルギーに変わる圧縮加熱が原因です。
宇宙空間を漂う隕石は秒速11km〜72km、地球の公転速度と同じかそれ以上のスピードで大気圏に突入します。
秒速20kmの1kgの隕石の運動エネルギーは約2億ジュール。TNT換算で約50kg分です。このエネルギーが一瞬で放出されます。
隕石は空気分子を前に押しのけて進みますが、そのスピードは音速の数十倍。
前に集まった空気は一瞬で押しつぶされ、衝撃波ができて激しく圧縮されます。
気体は圧縮されると温度が上がる、これはピストンを急激に押し込むと空気が熱くなるのと同じ原理です。
このラム加熱・衝撃波加熱で隕石の前方に数千℃の高温プラズマのカーテンができます。
停滞温度はおおよそ T ≒ T0 + v² / 2Cp で見積もられ、20km/sだと理論上 2万℃以上になります。実際は輻射で逃げるので数千℃ですが、それでも十分に溶融・気化する温度です。
摩擦熱もわずかにありますが、空気は連続体で隕石表面が滑るような摩擦ではなく、分子が次々と衝突・加熱されるため、摩擦が主因ではないのがポイントです。
その高温のプラズマが隕石表面を包み込みます。
表面温度は2000℃〜3000℃を超え、石質なら融点を超えて溶け、金属質なら蒸発します。
この過程をアブレーションと言います。表面が蒸発して吹き飛ぶため、尾を引いて「燃えている」ように見えます。
実際は化学反応による燃焼ではなく、加熱による気化と、気化した隕石物質と周囲の空気分子が発光する現象です。酸素がなくても光ります。
小さい隕石ほど表面積が大きく、減速も早いので大気圏内で完全に気化して消えます。これが流れ星です。
大きい隕石は運動エネルギーが大きく、表面が蒸発しても芯が残り、減速しながら地面まで届きます。これが隕石となります。
要するに、空気の抵抗で急激に減速する際に運動エネルギーが熱に変わり、衝撃波で空気が極高温になる。隕石はその高温に晒されて溶けて蒸発する、というのが大気圏突入の「燃える」原理です。
最近のコメント