Raspberry PI 3
更新:2025-04-25 下村清 / sameon@asahi-net.email.ne.jp
目 次
SWI-PROLOG 日本語を使う (2025-04-25 作成)
trealla-prolog install (2025-04-06 作成)
cu-prolog install (2025-04-03 作成)
prolog論理学真理表 (2025-04-21 修正)
Wii リモコン・ヌンチャク (2025-03-26 修正)
NFT -> LOG -> ulogd2 -> mariadb(mysql) db (2025-03-11 作成)
Raspbery pi PICO-W micropythonをソースから作る (2025-03-10 修正)
NFT -> LOG -> ulogd2 -> SQLITE3 db (2025-02-27 作成)
USB WIFI アダプタで、Wifi AP ルーター (2025-02-26 修正)
USB SSDブート, NVMe SSD, SD card 切り替え (2025-02-19 修正)
bookworm - podmanインストール (2025-02-03 作成)
ラジコ インストール (2025-01-29 作成)
bookworm - Dockerインストール (2025-01-20 修正)
ftpd インストール (2024-12-20 作成)
MIDIシンセサイザ (2024-12-17 修正)
Apache + FLASK + Flask.BASIC.Auth (2024-12-03 修正)
Raspbery pi OS (2024-11-19 更新)
行列式計算2 (2024-10-03 修正)
順列生成 (2024-09-18 作成)
余因子展開逆行列計算2(2024-09-17 作成)
行列計算 ガウスザイディル計算(2024-09-14 修正)
逆行列計算2.1(2024-09-14 修正)
Doolittle法でLU分解(2024-09-12 作成)
Gauss-Jordan消去・完全ピポッド法(2024-09-03 作成)
CROUT法LU分解(2024-08-31 修正)
行列 LU分解・行列式計算・方程式解法(2024-08-26修正)
行列・方程式解法ー逆行列 その他手順2題(2024-08-21修正)
行列式計算(2024-07-31修正)
行列・ガウスの消去法で方程式の解法(2024-07-28修正)
行列・階数(Rank)計算(2024-07-26修正)
mouspad メニューがない(2024-07-25作成)
余因子展開逆行列計算(2024-07-08作成)
HILL暗号復号キー(2024-06-15作成)
HILL暗号(2024-06-14修正)
heirloom-doctools 色(2024-05-12作成)
heirloom-doctools EQN(2024-05-11作成)
heirloom-doctools(2024-05-15修正)
固有値計算比較テスト(2024-04-17作成)
行列 dot()計算(2024-04-10作成)
行列 四則演算(2024-04-10作成)
非対称行列固有値計算(2024-04-07作成)
行列 固有値計算検算(2024-04-05修正)
行列 固有値計算(2024-03-31修正)
RaspiでVisual Studio Codeデバッグ(2024-03-23修正)
juliaインストール、実行(2024-03-21作成)
マシンイプシロン(2024-03-20修正)
IEEE754 丸め (2024-03-10修正)
Raspberry-pi 5(2024-03-11修正)
BITBANGソフトウェアI2C(2024-02-25作成)
seed stutio XIAO ESP32S3 Micropythonインストール(2024-01-17作成)
PICO-W bleキーボード(2023-12-20作成修正)
オートフォーカスカメラIMX519 INSTALL(2023-12-01更新)
NFS ポート番号固定設定(2023-11-18更新)
Google翻訳(2023-11-09更新)
ENC28J60 LANアダプタ Micropython WEB Serverプログラム (2023-09-21作成)
ENC28J60 LANアダプタ PYTHONプログラム (2023-09-07作成)
抵抗−2RラダーDAC (2023-09-07作成)
Raspberry Pi Bullseye OS にCAN ボード追加(2023-07-12修正)
Raspberry Pi PICO CAN 通信(2023-07-12修正)
RasPI PICO LANケーブル接続(2023-06-29追加)
雑誌MagPi (2023-06-24追加)
RasPI ZERO W5500,ENC28J60 LANアダプタ接続(2023-08-07修正)
OCTAVE GPIO(2023-06-13追加)
Raspberry piの小ワザ(2023-06-25更新)-A>
USBシリアルケーブルでシリアルコンソール追加(2023-05-23追加)
Micropython TELNET サーバー(2023-05-23追加)
Raspberry pi PICO W (2023-11-02修正)
jupyter notebook, scikit-learn インストール(2023-03-07更新)
SONY Xperia Ace III SO-53C MTP接続
GITコマンド
(A+B)**N の式展開
連分数
ジャクソン構造図
Stanford CoreNLP
Raspberry pi PICO
TinyBasic Plus for PICO
CP/M エミュレータ
BLE HID Keyboard
発音辞書検索
ICカードリーダ Opensc・PCSCD
DrRacket PLOT, SICP
Raspberry pi 3A+ HDDブート
Device Driverを作る
GNUCOBOL 3.0 インストール
Kermitを使う
DNS - unbound, DHCP - isc-dhcp-server
mysql, sqlite3, php7 インストール
Apacheでユーザ権限でCGI,PHP実行
ファイアーウォールの設定
HTTPSインストール
apache2.4インストール
WordPressインストール
RASPBERRY PI インストール HDDーBOOTの場合
パッケージ、ファーム アップデート
日本語テキスト読み上げインストール
gitをソースからインストール
UTF-8記号一覧
shell script 引数1をAWKスクリプトに埋め込む
chkconfig
cp タイムスタンプも
dig command
Full Path 表示
port 番号とアプリを調べる
shellスクリプトcgi
ディレクトリだけ表示 tree
ディレクトリ階層指定 tree
パッケージ登録内容表示
ブレース展開 csh, bash
ユーザディレクトリの移動
ユーザ追加
壁紙のあるところ
標準出力&エラー出力 標準出力
標準出力&エラー出力をすてる
2025-04-25 「SWI-PROLOG 日本語を使う」
参照:
「Prologを学ぶ ーー文化とその実践ーー」 杉崎昭生著 海文堂 1995
$ nano 事実.pl
...
醸造酒(ビール).
醸造酒(ワイン).
蒸留酒(ブランデー).
蒸留酒(ウィスキー).
こはく色(ブランデー).
こはく色(ウィスキー).
こはく色(ビール).
淡黄色(ワイン).
...
$ swipl 事実.pl
Welcome to SWI-Prolog (threaded, 64 bits, version 9.0.4)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.
For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).
?- 醸造酒(ブランデー).
false.
?- 醸造酒(ビール).
true.
$ nano 階乗.pl
...
階乗(0,1) :- !.
階乗(1,1) :- !.
階乗(_値N, _階乗値) :-
_値N1 is _値N - 1,
階乗(_値N1, _階乗値1),
_階乗値 is _階乗値1 * _値N.
...
$ swipl 階乗.pl
Welcome to SWI-Prolog (threaded, 64 bits, version 9.0.4)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.
For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).
?- 階乗(5, _階乗値).
_階乗値 = 120.
?- 階乗(0, _階乗値).
_階乗値 = 1.
2025-04-06 「trealla-prolog install」
https://github.com/trealla-prolog/trealla
Trealla Prolog
$ git clone https://github.com/trealla-prolog/trealla.git
$ cd trealla
$ cd src
$ sudo apt install libreadline-dev libffi-dev libssl-dev xxd
$ make
インストールは、
$ ln -s $(pwd)/tpl ~/bin/tpl
ライブラリ読み込み指定
$ nano ~/.tplrc
ーーーーーーーーーーーーーーーーー
:-use_module(library(assoc)).
:-use_module(library(ordsets)).
ーーーーーーーーーーーーーーーーー
prolog真理表で使ったtruth_t3.plを修正する。
$ nano truth_t3.pl
...
pl_eval(~Phi, V) :-
not(pl_eval(Phi, V)). <<== \+ を not()に修正
...
実行。
$ tpl truth_t3.pl
?- pl_print_truth_table(((p => q) /\ p) => q).
'Truth table for '=>(/\(=>(p,q),p),q)
p q formula
false false true
false true true
true false true
true true true
true.
?- pl_print_truth_table((~p /\ (p \/ q)) => q).
'Truth table for '=>(/\(~(p),\/(p,q)),q)
p q formula
false false true
false true true
true false true
true true true
true.
?- pl_print_truth_table( (p /\ (p \/ q)) => ~q).
'Truth table for '=>(/\(p,\/(p,q)),~(q))
p q formula
false false true
false true true
true false true
true true false
true.
?- pl_print_truth_table( (p /\ ~(p <=> q)) => ~q).
'Truth table for '=>(/\(p,~(<=>(p,q))),~(q))
p q formula
false false true
false true true
true false true
true true true
true.
?- pl_print_truth_table(((((p => q) => ( ~r => ~s)) => r) => u) => ((u => p) => (s => p))).
'Truth table for '=>(=>(=>(=>(=>(p,q),=>(~(r),~(s))),r),u),=>(=>(u,p),=>(s,p)))
p q r s u formula
false false false false false true
false false false false true true
false false false true false true
false false false true true true
false false true false false true
false false true false true true
false false true true false true
false false true true true true
false true false false false true
false true false false true true
false true false true false true
false true false true true true
false true true false false true
false true true false true true
false true true true false true
false true true true true true
true false false false false true
true false false false true true
true false false true false true
true false false true true true
true false true false false true
true false true false true true
true false true true false true
true false true true true true
true true false false false true
true true false false true true
true true false true false true
true true false true true true
true true true false false true
true true true false true true
true true true true false true
true true true true true true
true.
?- halt.
2025-04-03 「cu-prolog install」
第五世代コンピュータプロジェクト・アーカイブスにあるCU-PROLOGをやってみようとしたが、
ソースsyspred1.cが面倒なことになってしまったので、検索していたら以下のところにあったので
やってみた。
PROLOG文法はSWI-PROLOGとは違うところがあるのでSWI-PROGのスクリプトはそのままでは動かない。
https://az-prolog.com/natural-language-processing/nlu/
CU-Prologダウンロード
Original CU-Prologダウンロード
Download クリック で、cuprolog.zip ダウンロード。
第五世代コンピュータプロジェクト・アーカイブスにあるソースプログラムとは内容が違うの、パッチを
作ったこちらのほうを使う。
SOFNEC改修ファイルダウンロード
Download クリック で、cuprolog_sofnec_patch.zip ダウンロード。
$ mkdir CU-PROLOG
$ cd CU-PROLOG
$ mv ~/ダウンロード/cuprolog.zip .
解凍する。
$ mv ~/ダウンロード/cuprolog_sofnec_patch.zip .
解凍する。
$ cd cuprolog/src # cu-prologのソースディレクトリ
$ chmod 666 *
$ patch -R < ../../cuprolog_sofnec_patch/cu64.patch
..
patching file funclist.h
Unreversed patch detected! Ignore -R? [n] y
;;
;;
全部パッチ 'y'
$ nano globalv.h
...
extern struct func *LIST,*CUNIFY;
extern struct term *NIL, *FAIL, *END_OF_FILE;
extern struct term *Anonymous_var;
extern struct pair *Anonymous_env;
extern struct clause *MFAIL;
extern struct term *XF_P, *YF_P, *FX_P, *FY_P, *XFX_P, *XFY_P, *YFX_P;
extern struct term *S_GLOBAL_VAR, *S_VAR, *S_INTEGER, *S_FLOAT;
extern struct term *S_STRING, *S_FILE_POINTER, *S_PST, *S_CLAUSE;
extern struct term *S_LIST, *S_FUNCTOR, *S_ATOM, *S_PSTOBJ;
extern struct term *S_EQ, *S_GREATER, *S_LESS;
...
"extern "を追加。
$ nano include.h
...
#define RASPI
...追加
$ chmod +w main.c
$ nano main.c
...
void heap_realloc() /* reallocate system/user heaps */
{
#if defined(WIN64) || defined(RASPI) <<==修正
free((char *)sheap); SHEAP_SIZE=SHEAP_SIZE*1.2; system_heap_alloc();
#else
...
$ make
ワーニングが出る。includeファイル、関数プロトタイプを設定すればなくなる。とりあえずは無視。
英文構文解析 実行。
$ ./cup3 ../sample/hpsg.p
>>> open ../sample/hpsg.p
******* cu - Prolog III Ver. 3.1 (July 6, 1994) *******
[COPYRIGHT] Institute for New Generation Computer Technology (ICOT)
Tokyo, Japan 1991-93
Type '%h' for help.
[Heap=1000K System_heap=2000K Env_heap=160K Cstr_heap=2000K
Ustack=100K Name_heap=50K]
****** end of file *******
CPU time = 0.000 sec (Constraints Handling = 0.000 sec)
_?-p([mary,meets,john]).
{head/verb, ph/[mary,meets,john], sc/[]}---1
|
|--{head/verb, ph/[mary,meets], sc/[noun]}---2
| |
| |--noun---[mary]
| |
| |__verb---[meets]
|
|__noun---[john]
category= {head/verb, ph/[mary,meets,john], sc/[]}
constraint=
true.
CPU time = 0.000 sec (Constraints Handling = 0.000 sec)
_?-p([mary,is,nice]).
{head/verb, ph/[mary,is,nice], sc/[]}---2
|
|--noun---[mary]
|
|__{head/verb, ph/[is,nice], sc/[noun]}---1
|
|--verb---[is]
|
|__adjective---[nice]
category= {head/verb, ph/[mary,is,nice], sc/[]}
constraint=
true.
CPU time = 0.000 sec (Constraints Handling = 0.000 sec)
_:-halt.
---- Quit cu-Prolog ? (y/n) ----y
'%Q'でプログラム終了
sample/jpsg.p は、日本語構文解析。
2025-04-14 「prolog論理学真理表」
https://www.sra.co.jp/public/sra/gsletter/
GSLetterNeo
全然関係ないことで検索していて見つけてしまったことから始まる。
◎Vol.153 DX? アジャイル? イノベーション? ― 思考する力、想像する力 / 土屋正人
この中にある↓
「思考の教室 ― じょうずに考えるレッスン」 戸田山和久著 NHK 出版 2020, 2023
を読んで、おもしろいなあでやってみようかと始めた。
「論理学をつくる」 戸田山和久著 名古屋大学出版会 2000, 2014
「思考の教室 」のつながりで。
他には。
「論証の教室 入門編」 倉田剛著 新曜社 2022
「思考の技術論」 鹿島茂著 平凡社
がある。
まずは論理学をプログラムするのは何かなとと思いつくのはPROLOG。
昔に、”第五世代コンピュータプロジェクト”でつかわれていたもの。
(https://www.airc.aist.go.jp/aitec-icot/ICOT/HomePage-J.html
「第五世代コンピュータプロジェクト・アーカイブスへようこそ!」)
SRA GSLetterNeo 「Vol.197 Pythonで始める論理プログラミング -SWI-Prolog編-」にあったもの
はRaspberry pi ではpython モジュールがみつからないのでとりあえずはswi-prologをインストールする。
$ sudo apt install swi-prolog
参考:
https://barrywatson.se/cl/cl_truth_table.html
Truth Table
論理学にはいつもついてまわる真理表を作るPROLOGがないかと検索して、何個か試したが上記の
「Truth Table」のスクリプトがよかったのでやってみた。これのPrologスクリプトのみをファイルにする。
python, c などとは違う演算子がある。
*** 基本 ***
?- pl_print_truth_table( p \/ q ).
'Truth table for 'p\/q
p q formula
false false false
false true true
true false true
true true true
true.
?- pl_print_truth_table( p /\ q ).
'Truth table for 'p/\q
p q formula
false false false
false true false
true false false
true true true
true.
?- pl_print_truth_table( p => q ). # →演算子
'Truth table for 'p=>q
p q formula
false false true
false true true
true false false
true true true
true.
?- pl_print_truth_table( p <=> q ). # ≡演算子
'Truth table for 'p<=>q
p q formula
false false true
false true false
true false false
true true true
true.
*********
例題は、「論理学をつくる」 戸田山和久著 名古屋大学出版会 2000, 2014 より
第Ⅰ部 第4章 4.2.7 妥当性、トートロジー性、論理的同値性の判定とタブロー
練習問題23 (6)トートロジー チェック
よりもらった。?- 以降を1行入力する。
$ swipl truth_t3.pl
■(6)(a)
?- pl_print_truth_table(((p => q) /\ p) => q).
'Truth table for '(p=>q)/\p=>q
p q formula
false false true
false true true
true false true
true true true
true.
■(6)(b)
?- pl_print_truth_table((~p /\ (p \/ q)) => q).
'Truth table for '~p/\(p\/q)=>q
p q formula
false false true
false true true
true false true
true true true
true.
■(6)(c)
?- pl_print_truth_table( (p /\ (p \/ q)) => ~q).
'Truth table for 'p/\(p\/q)=> ~q
p q formula
false false true
false true true
true false true
true true false
true.
■(6)(d)
?- pl_print_truth_table( (p /\ ~(p <=> q)) => ~q).
'Truth table for 'p/\ ~ (p<=>q)=> ~q
p q formula
false false true
false true true
true false true
true true true
true.
■(6)(e)
?- pl_print_truth_table(((((p => q) => ( ~r => ~s)) => r) => u) => ((u => p) => (s => p))).
'Truth table for '((((p=>q)=> ~r=> ~s)=>r)=>u)=>(u=>p)=>s=>p
p q r s u formula
false false false false false true
false false false false true true
false false false true false true
false false false true true true
false false true false false true
false false true false true true
false false true true false true
false false true true true true
false true false false false true
false true false false true true
false true false true false true
false true false true true true
false true true false false true
false true true false true true
false true true true false true
false true true true true true
true false false false false true
true false false false true true
true false false true false true
true false false true true true
true false true false false true
true false true false true true
true false true true false true
true false true true true true
true true false false false true
true true false false true true
true true false true false true
true true false true true true
true true true false false true
true true true false true true
true true true true false true
true true true true true true
true.
◇◇トートロジー◇◇
参考:「数理論理学」 戸次大介著 東京大学出版会 2012
より
第一部 一階論理の統語論と意味論
第3章 一階命題論理:統語論と意味論
から
◎排中律
?- pl_print_truth_table( p \/ ~p ).
◎矛盾律
?- pl_print_truth_table( ~(p /\ ~p) ).
◎結合律
?- pl_print_truth_table(( p /\ ( q /\ r)) <=> ((p /\ q ) /\ r) ).
?- pl_print_truth_table(( p \/ ( q \/ r)) <=> ((p \/ q ) \/ r) ).
◎交換律
?- pl_print_truth_table(( p \/ q) <=> ( q \/ p) ).
?- pl_print_truth_table(( p /\ q) <=> ( q /\ p) ).
◎吸収律
?- pl_print_truth_table(( p /\ (p \/ q)) <=> p ).
?- pl_print_truth_table(( p \/ (p /\ q)) <=> p ).
◎冪等律
?- pl_print_truth_table(( p \/ p ) <=> p ).
?- pl_print_truth_table(( p /\ p ) <=> p ).
◎縮小律
?- pl_print_truth_table(( p /\ q ) => p ).
?- pl_print_truth_table(( p /\ q ) => q ).
◎拡大律
?- pl_print_truth_table(p => ( p \/ q ) ).
?- pl_print_truth_table(q => ( p \/ q ) ).
◎分配律
?- pl_print_truth_table(( p \/ (q /\ x)) <=> ((p \/ q) /\ (p \/ x)) ).
?- pl_print_truth_table(( p /\ (q \/ x)) <=> ((p /\ q) \/ (p /\ x)) ).
◎同一律
?- pl_print_truth_table( p => p ).
◎推移律
?- pl_print_truth_table((( p => q ) /\ ( q => x)) => (p => x) ).
◎移入律
?- pl_print_truth_table(( p => q => x) => (p => q => x) ).
◎移出律
?- pl_print_truth_table(( p /\ q => x) => (p => q => x) ).
◎ドゥ・モルガンの法則
?- pl_print_truth_table( (~( p /\ q )) <=> (~p \/ ~q) ).
?- pl_print_truth_table( (~( p \/ q )) <=> (~p /\ ~q) ).
◎対偶律
?- pl_print_truth_table( ( p => q ) <=> (~q => ~p) ).
◎二重否定律
?- pl_print_truth_table( p <=> ~(~p) ).
◎前件肯定式
?- pl_print_truth_table( p /\ (p => q) => q ).
◎選言的三段論法
?- pl_print_truth_table( ~p /\ (p \/ q) => q ).
◎構成的両刃論法
?- pl_print_truth_table( (p => x) => (q => x) => (p \/ q => x) ).
参考:
記号論理学 藤川吉美著 大竹出版 1986,1995
?- pl_print_truth_table( p <=> p ).
?- pl_print_truth_table( ~(~p) <=> p ).
?- pl_print_truth_table( ~(~p) => p ).
?- pl_print_truth_table( (p => q ) /\ p => q).
?- pl_print_truth_table( (p <=> q ) <=> ( q <=> p )).
?- pl_print_truth_table( (p => q ) /\ ~q => ~p ).
?- pl_print_truth_table( (p => q ) /\ (p => ~q ) => ~p ).
?- pl_print_truth_table( (p <=> q ) /\ (q <=> r ) => ( p <=> r) ).
?- pl_print_truth_table( (p => (q => r) ) => (p /\ q => r ) ).
?- pl_print_truth_table( (p /\ q => r) => (p => ( q => r )) ).
?- pl_print_truth_table( (p => q ) => (( q => r) => ( p => r )) ).
?- pl_print_truth_table( (p => ( q => r )) <=> ( q => ( p => r ) ) ).
?- pl_print_truth_table( (p => r ) /\ ( q => r) => ( p \/ q => r ) ).
?- pl_print_truth_table( p /\ (q \/ r ) <=> ( p /\ q ) \/ ( p /\ r ) ).
?- pl_print_truth_table( p \/ (q /\ r ) <=> ( p \/ q ) /\ ( p \/ r ) ).
?- pl_print_truth_table( p => ( q => p ) ).
?- pl_print_truth_table( ~(~p) => p \/ q ).
?- pl_print_truth_table( ~p => p => q ).
?- pl_print_truth_table( p => ( ~p => q ) ).
?- pl_print_truth_table( ( ~p => p ) => p ).
?- pl_print_truth_table( p \/ q <=> ~p => q ).
?- pl_print_truth_table( p => q <=> ~p \/ q ).
?- pl_print_truth_table( p => ( q => p /\ q ) ).
?- pl_print_truth_table( p /\ ( q \/ ~q ) <=> p ).
?- pl_print_truth_table( p \/ ( q /\ ~q ) <=> p ).
?- pl_print_truth_table( p => q <=> ~( p /\ ~q ) ).
?- pl_print_truth_table( (p <=> q) => ( p => q ) ).
?- pl_print_truth_table( (p <=> q) => ( q => p ) ).
?- pl_print_truth_table( p /\ q <=> ~( p => ~q ) ).
?- pl_print_truth_table( p /\ q <=> ~( ~p \/ ~q ) ).
?- pl_print_truth_table( p \/ q <=> ~( ~p /\ ~q ) ).
?- pl_print_truth_table( ( p => q ) <=> ( ~(~p) => q ) ).
?- pl_print_truth_table( p /\ ( q /\ ~q ) <=> q /\ ~q ).
?- pl_print_truth_table( p \/ ( q \/ ~q ) <=> q \/ ~q ).
?- pl_print_truth_table( ( p => q ) => ( p /\ r => q /\ r ) ).
?- pl_print_truth_table( ( p => q ) => ( p \/ r => q \/ r ) ).
?- pl_print_truth_table( ( p => ( q => r) ) <=> ( p /\ q => r ) ).
?- pl_print_truth_table( p => ( ( p /\ q => r ) => ( q => r ) ) ).
?- pl_print_truth_table( ( p <=> q ) <=> ( p => q ) /\ ( q => p ) ).
?- pl_print_truth_table( ( p => q ) /\ ( p /\ r ) => ( q /\ r ) ).
?- pl_print_truth_table( ( p => q ) /\ ( p \/ r ) => ( q \/ r ) ).
?- pl_print_truth_table( ( p /\ q => r ) => ( p /\ ~r => ~q ) ).
?- pl_print_truth_table( ( p /\ q => r ) => ( ~r /\ q => ~p ) ).
?- pl_print_truth_table( ( p /\ ~q => ~r ) => ( p /\ r => q ) ).
?- pl_print_truth_table( ( p => r ) => ( ( p => q ) => ( p => r) ) ).
?- pl_print_truth_table( ( p => q ) => ( ( q => p ) => ( p <=> q ) ) ).
?- pl_print_truth_table( ( p => r ) => ( ( q => r ) => ( p /\ q => r ) ) ).
?- pl_print_truth_table( ( p => r ) => ( ( q => r ) => ( p \/ q => r ) ) ).
?- pl_print_truth_table( ( p => ( q => r ) ) <=> ( ~( p => ~q ) => r ) ).
?- pl_print_truth_table( ( ~( p => q ) => r ) <=> ( p => ( ~q => r ) ) ).
?- pl_print_truth_table( ( p => q ) => ( ( p => ( q => r ) ) => ( p => r)) ).
?- pl_print_truth_table( ( ( p => q ) => r ) <=> ( ~p => r ) /\ ( q => r ) ).
?- pl_print_truth_table( ( p => q ) /\ ( r /\ s ) => ( p /\ r => q /\ s ) ).
?- pl_print_truth_table( ( p => q ) => ( ( r => s ) => ( p /\ r => q /\ s ) ) ).
?- pl_print_truth_table( ( s => p ) => ( ( p /\ q => r) => ( s /\ q => r )) ).
?- pl_print_truth_table( ( p /\ q => r ) => ( ( s => q ) => ( p /\ s => r ) ) ).
?- pl_print_truth_table( ( r /\ s ) => ( ( p /\ q => r ) => ( q /\ p => s ) ) ).
参照:
現代論理学 末木、坂井、大出著 光文堂 1978
?- pl_print_truth_table( p => ( ~( ~ p )) ).
?- pl_print_truth_table( ~( p /\ ~p ) ).
?- pl_print_truth_table( ( ( p => q ) /\ p ) => q ).
?- pl_print_truth_table( ( ( p => q ) /\ ~q ) => ~p ).
参考:
記号論理学の原理 H・ライヘンバッハ著 石本新訳 大修館書店 1982
2.命題計算 8 可能な演算の外観、トートロジー
?- pl_print_truth_table( p \/ p <=> p ). 同一律
?- pl_print_truth_table( p /\ p <=> p ). 同一律
?- pl_print_truth_table( p => ~p <=> ~p ). 背理法
?- pl_print_truth_table( p /\ ( q \/ r) <=> p /\ q \/ p /\ r ). 第1分配法則
?- pl_print_truth_table( p \/ q /\ r <=> ( p \/ q ) /\ ( p \/ r ) ). 第2分配法則
?- pl_print_truth_table( (p \/ q) /\ (r \/ s) <=> p /\ r \/ q /\ r \/ p /\ s \/ q /\ s ). 二重分配法則
?- pl_print_truth_table( p/\ q \/ r /\ s <=> ( p \/ r ) /\ ( q \/ r ) /\ ( p \/ s ) /\ ( q \/ s ) ). 二重分配法則
?- pl_print_truth_table( ~( p /\ q ) <=> ~p \/ ~q ). 否定線の分解
?- pl_print_truth_table( ~( p \/ q ) <=> ~p /\ ~q ). 否定線の分解
?- pl_print_truth_table( p \/ q /\ ~q <=> p ). 恒偽項の除去
?- pl_print_truth_table( p \/ ~p /\ q <=> p \/ q ). 否定の吸収
?- pl_print_truth_table( p => q <=> ~p \/ q ). 含意の消去
?- pl_print_truth_table( p => q <=> ~q => ~p ). 対偶
?- pl_print_truth_table( (p => q) /\ (p => r) <=> p => q /\ r ). 含意統合
?- pl_print_truth_table( (p => r) /\ (q => r) <=> p \/ q => r ). 含意統合
?- pl_print_truth_table( (p => q) \/ (p => r) <=> p => q \/ r ). 含意統合
?- pl_print_truth_table( (p => r) \/ (q => r) <=> p /\ q => r ). 含意統合
?- pl_print_truth_table( (p <=> q) <=> p /\ q \/ ~p /\ ~q ). 同値の消去
?- pl_print_truth_table( ~(p <=> q) <=> ( p <=> ~q ) ). 同値の否定
?- pl_print_truth_table( (p <=> q) <=> ( ~p <=> ~q ) ). 同値な項の否定
?- pl_print_truth_table( p => p \/ q ). 項の追加
?- pl_print_truth_table( p /\ q => p ). 2つの前提からその1つへの含意
?- pl_print_truth_table( ~p => ( p => q ) ). 含意の追加
?- pl_print_truth_table( (p => q ) => ( p => q \/ r ) ). 結論の追加
?- pl_print_truth_table( (p => q ) => ( p /\ r => q ) ). 前提の追加
?- pl_print_truth_table( (p \/ r => q ) => ( p => q ) ). 前提の除去
?- pl_print_truth_table( (p => q /\ r ) => ( p => q ) ). 結論の除去
?- pl_print_truth_table( (p => q ) /\ ( r => s ) => ( p \/ r => q \/ s ) ). 統合された含意
?- pl_print_truth_table( (p => q ) /\ ( q => r ) => ( p => r ) ). 含意の推移性
参考:
「論理学をつくる」 戸田山和久著 名古屋大学出版会 2000, 2014
pl_print_truth_table( ( ~q /\ ( p => q ) ) => ~p). # 否定式
pl_print_truth_table( ( ( p /\ p ) => r ) => ( p => ( q => r))). # 移出律
pl_print_truth_table( ( ( p => r ) /\ ( q => r ) ) => ( ( p \/ q ) => r)). # 構成的両刀論法
pl_print_truth_table( ( ( p => q) => p ) => p ). # パースの法則
pl_print_truth_table( p => ( q => ( p /\ q ) ) ). # law of adjunction
pl_print_truth_table( ( p => q ) <=> ( ~p \/ q )).
pl_print_truth_table( ( p => q ) <=> ~( p /\ ~q)).
pl_print_truth_table( ( p => q ) => ( ( p => r ) => ( p => ( q /\ r ) ) ) ). # 合成律
蛇足。
■ P → Q は、 (〜p)V Q に等しい
?- pl_print_truth_table( (p => q) <=> ( (~p) \/ q)).
'Truth table for 'p=>q<=> ~p\/q
p q formula
false false true
false true true
true false true
true true true
true.
■ P ↔ Q は、 (p→Q)^(Q→P)に等しい
?- pl_print_truth_table( (p <=> q) <=> ( (p => q) /\ (q => p))).
'Truth table for '(p<=>q)<=>(p=>q)/\(q=>p)
p q formula
false false true
false true true
true false true
true true true
true.
■・・・論理演算子 優先順位・・・
③ ② ①
?- pl_print_truth_table( p <=> q => p \/ q ).
'Truth table for 'p<=>q=>p\/q
p q formula
false false false
false true false
true false true
true true true
true.
?- pl_print_truth_table( p <=> (q => (p \/ q))).
'Truth table for 'p<=>q=>p\/q
p q formula
false false false
false true false
true false true
true true true
true.
③ ② ①
?- pl_print_truth_table( p <=> q => p /\ q ).
'Truth table for 'p<=>q=>p/\q
p q formula
false false false
false true true
true false true
true true true
true.
?- pl_print_truth_table( p <=> (q => (p /\ q)) ).
'Truth table for 'p<=>q=>p/\q
p q formula
false false false
false true true
true false true
true true true
true.
2025-03-26 「Wii リモコン・ヌンチャク」
ニンテンドーWiiのリモコン、ヌンチャクがリサイクルショップで安いので触ってみた。
両方に加速度センサが入っている。
リモコンはBluetooth、ヌンチャクはI2Cで接続できる。
(1)Blutooth接続
参照:
https://www.raspberrypi-spy.co.uk/2013/02/nintendo-wii-remote-python-and-the-raspberry-pi/
Nintendo Wii Remote, Python and The Raspberry Pi
接続方法は何種類かあるが確実につなげるpython3-cwiidでしてみる。
wmguiプログラムも使える。
$ sudo apt install python3-cwiid
$ nano cwiid-remote.py
...
import time
import cwiid
print('ボタン①とボタン② か、電池ケース内のSYNCボタンを押してください。...')
while True: # 2回め以降の接続がうまく行かないので再接続するため
try:
wii = cwiid.Wiimote()
break
except:
print('接続失敗...')
time.sleep(0.2)
else:
exit(0)
time.sleep(0.1)
wii.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_ACC | cwiid.RPT_NUNCHUK | cwiid.RPT_IR
# ボタン、加速度センサ、ヌンチャク、赤外線センサ 検出 設定
while True:
if (wii.state['buttons'] - cwiid.BTN_PLUS - cwiid.BTN_MINUS == 0):
print( '\nリモコン接続 (x)断')
wii.rumble = 1
time.sleep(0.2)
wii.rumble = 0
exit(0)
print("---------")
print(wii.state)
time.sleep(1)
...
実行
+ボタンとーボタン 同時押しでプログラム終了。
$ python cwiid-remote.py
...
ボタン①とボタン② か、電池ケース内のSYNCボタンを押してください。...
No wiimotes found
接続失敗...
No wiimotes found
接続失敗...
No wiimotes found
接続失敗...
:::
---------
{'rpt_mode': 30, 'led': 0, 'rumble': 0, 'battery': 104, 'ext_type': 1, 'error': 0, 'buttons': 0, 'acc': (128, 128, 151), 'ir_src': [None, None, None, None], 'nunchuk': {'stick': (123, 128), 'acc': (172, 136, 105), 'buttons': 0}}
::: *リモコン、ヌンチャクを傾けたり、キーを押すとbutton, accの値が変化する
---------
{'rpt_mode': 30, 'led': 0, 'rumble': 0, 'battery': 104, 'ext_type': 1, 'error': 0, 'buttons': 0, 'acc': (128, 125, 151), 'ir_src': [{'pos': (928, 590)}, {'pos': (835, 601)}, {'pos': (766, 713)}, None], 'nunchuk': {'stick': (123, 128), 'acc': (173, 136, 105), 'buttons': 0}}
::: *赤外線リモコンをWIIリモコンIPセンサに向けてキーを押すと検出する
---------
{'rpt_mode': 30, 'led': 0, 'rumble': 0, 'battery': 90, 'ext_type': 0, 'error': 0, 'buttons': 0, 'acc': (138, 131, 150), 'ir_src': [None, None, None, None]}
::: *ヌンチャクを抜くと'nunchuk':キーワードはなくなる
リモコン接続 (x)断
....
WII 赤外LED センサバーの場合
・通常カメラで見た
・赤外カメラで見た
..
{'rpt_mode': 30, 'led': 0, 'rumble': 0, 'battery': 77, 'ext_type': 0, 'error': 0, 'buttons': 4116, 'acc': (115, 118, 144), 'ir_src': [{'pos': (333, 407), 'size': 3}, {'pos': (649, 340), 'size': 3}, None, None]}
..
2点が検出される。向きを変えると1個、なしとなる。
(2) I2C接続
参照:
https://htlab.net/electronics/game/wii-remote-extension-controller/
Wiiリモコン拡張コントローラープロトコル解析
https://github.com/rkrishnasanka/ArduinoNunchuk/blob/master/README.md
Arduino Nunchuk Library
配線:
nunchuck sca(data) ---- raspi GPIO-02
scl(clock) ---- GPIO-03
GND ---- GND
コネクタは、両面プリント基板に2.54mmピッチで3本 ■ ■ ■ 両面にスジを入れ各スジが接続していないようにして
おいて、その端子にはんだ付けするなりしてコネクタの穴に差し込めば良い。スジの長さはコネクタの穴の深さで決まる。
$ nano i2c-nunchuck.py
...
#!/usr/bin/env python
import smbus
import time
def get_id(bus0, address):
time.sleep(0.1)
bus0.write_byte(address, 0xFA)
time.sleep(0.1) # すぐだとデータが書き込めない
print("識別子: ",end='')
for _ in range(6):
print("%02X " % (bus0.read_byte(address)),end='')
print('\n -- 00 00 A4 20 00 00 : ヌンチャク')
def main():
print("**** WII ヌンチャク接続 ****")
bus = smbus.SMBus(1)
address = 0x52
get_id(bus, address)
time.sleep(0.1)
# === 最初
bus.write_byte(address,0xF0)
print("暗号フラグ:",hex(bus.read_byte(address)))
# === 0x55:暗号解除 それ以外は暗号化
time.sleep(0.1)
print("<暗号化解除>")
bus.write_byte_data(address, 0xF0, 0x55) # 暗号化解除
time.sleep(0.1) # すぐだとデータが書き込めない
# === 暗号化解除書き込み後
bus.write_byte(address,0xF0)
print("暗号フラグ:",hex(bus.read_byte(address)))
# === 0x55:暗号解除 それ以外は暗号化
get_id(bus, address)
time.sleep(0.1) # すぐだとデータが書き込めない
while True:
try:
data = [0] * 6
bus.write_byte(address,0x00)
time.sleep(0.005) # すぐだとデータが読み込めない
for i in range(6):
data[i] = bus.read_byte(address)
#
# JOY stick , Acc X,y,Z and Button C,Z
# 8 bits * 6 Bytes
# +========================================+
# 0 | Joy X 7-0 bit |
# 1 | Joy Y 7-0 bit |
# 2 | Acc x 9-2 bit |
# 3 | Acc y 9-2 bit |
# 4 | Acc z 9-2 bit |
# 5 | Az 1-0 | Ay 1-0 | Ax 1-0 | Cb 1 | Zb 1 |
# +========================================+
# x-axis, y-axis = 0 : 水平
# x-axis > 0 : ジョイスティック上向き
#
b = (data[5] & 0x03) ^ 3
xaxis = data[2] << 2
xaxis |= (data[5] >> 2) & 0x03
yaxis = data[3] << 2
yaxis |= (data[5] >> 4) & 0x03
zaxis = data[4] << 2
zaxis |= (data[5] >> 6) & 0x03
print( "Analog X: %d" %(data[0]/2 - 62) )
print( "Analog Y: %d" %(data[1]/2 - 64) )
print( "X-axis: %d" %(xaxis - 512))
print( "Y-axis: %d" %(yaxis - 512))
print( "Z-axis: %d" %(zaxis - 512))
print( "Button: %s%s" % (" ZC"[b&2]," ZC"[b&1]))
time.sleep(0.2)
except KeyboardInterrupt:
print("\x1b[2K")
break
except IOError as e:
print( e)
print("")
break
for _ in range(6):
print("\x1b[1F\x1b[2K", end='')
if __name__ == '__main__':
main()
...
実行
$ python i2c-nunchuck.py
...
**** WII ヌンチャク接続 ****
識別子: FF FF FF FF FF FF
-- 00 00 A4 20 00 00 : ヌンチャク
暗号フラグ: 0xff
<暗号化解除>
暗号フラグ: 0x55
識別子: 00 00 A4 20 00 00
-- 00 00 A4 20 00 00 : ヌンチャク
Analog X: 0
Analog Y: 0
X-axis: -20
Y-axis: 15
Z-axis: 194
Button: Z
...
一度実行後は電源オフにしない限り識別子は正しく読める。
暗号化解除は、0xF0, 0x55 書き込みが確実であった。白、黒ヌンチャクとも。
暗号復号は (8ビットデータ ^ 0x17) + 0x17。
2025-03-11 「NFT -> LOG -> ulogd2 -> mariadb(mysql) db」
NFTABLEのログをMARIADB(Mysql)データベースに書き込んでみた。
SQLITE3書き込みができているのを前提で。
(1) db インストール
$ sudo apt install -y mariadb-server python3-mysqldb
$ sudo service mysql restart
$ sudo mysql_secure_installation
...
Enter current password for root (enter for none): <Enter>
Switch to unix_socket authentication [Y/n] y<Enter>
Change the root password? [Y/n] y<Enter>
New password: ルートパスワード<Enter>
Re-enter new password: ルートパスワード<Enter>
Remove anonymous users? [Y/n] y<Enter>
Disallow root login remotely? [Y/n] y<Enter>
Remove test database and access to it? [Y/n] y<Enter>
Reload privilege tables now? [Y/n] y<Enter>
...
データベースの初期設定とルートパスワード設定。
$ nano tmysql.sh
----
#!/bin/bash
echo "MySql Install "
cat << 'EOF'| sudo mysql -u root -pルートパスワード
show variables like 'char%';
create user 'tuser'@'localhost' identified by 'tuserpp';
create database tdb;
grant all privileges on tdb.* to 'tuser'@'localhost';
quit
EOF
cat << 'EOF' | tee mysql.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import MySQLdb
try:
connect0 = MySQLdb.connect(
host="localhost",
port=3306,
db='tdb',
user='tuser',
passwd='tuserpp',
charset="utf8"
)
cursor = connect0.cursor()
print("OK<br>")
except:
print("NG<br>")
cursor.close()
connect0.close()
EOF
echo "----TEST Mysql----"
python ./mysql.py
---
MYSQLデータベースの動作テスト。
$ sh tmysql.sh
...
MySql Install
Variable_name Value
character_set_client utf8mb3
character_set_connection utf8mb3
character_set_database utf8mb4
character_set_filesystem binary
character_set_results utf8mb3
character_set_server utf8mb4
character_set_system utf8mb3
character_sets_dir /usr/share/mysql/charsets/
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import MySQLdb
try:
connect0 = MySQLdb.connect(
host="localhost",
port=3306,
db='tdb',
user='tuser',
passwd='tuserpp',
charset="utf8"
)
cursor = connect0.cursor()
print("OK<br>")
except:
print("NG<br>")
cursor.close()
connect0.close()
----TEST Mysql----
OK<br>
...
mariadb(MYSQL)動作テストOK
ULOGD2用のデータベース ユーザ登録。
$ mysql -u root -p
Enter password:
> create user 'mulogd'@'localhost' identified by 'パスワード';
> create database nulog;
> grant all privileges on nulog.* to 'mulogd'@'localhost';
> grant file on *.* to 'mulogd'@'localhost';
> flush privileges;
> quit
....
ULOGD2用テーブルの作成。
$ gzip -dc /usr/share/doc/ulogd2/mysql-ulogd2.sql.gz | mysql -D nulog -u mulogd -p
$ mysql -u mulogd -p nulog < sqlm.sql
$ nano sqlm.sql
..
drop table IF EXISTS t_ip_prot;
CREATE TABLE t_ip_prot (id int unsigned, header_prot text );
insert into t_ip_prot values ( 0 ,"HOPOPT");
insert into t_ip_prot values ( 1 ,"ICMP");
insert into t_ip_prot values ( 2 ,"IGMP");
insert into t_ip_prot values ( 3 ,"GGP");
insert into t_ip_prot values ( 4 ,"IP-in-IP");
insert into t_ip_prot values ( 5 ,"ST");
insert into t_ip_prot values ( 6 ,"TCP");
insert into t_ip_prot values ( 7 ,"CBT");
insert into t_ip_prot values ( 8 ,"EGP");
insert into t_ip_prot values ( 9 ,"IGP");
insert into t_ip_prot values ( 10 ,"BBN-RCC-MON");
insert into t_ip_prot values ( 11 ,"NVP-II");
insert into t_ip_prot values ( 12 ,"PUP");
insert into t_ip_prot values ( 13 ,"ARGUS");
insert into t_ip_prot values ( 14 ,"EMCON");
insert into t_ip_prot values ( 15 ,"XNET");
insert into t_ip_prot values ( 16 ,"CHAOS");
insert into t_ip_prot values ( 17 ,"UDP");
insert into t_ip_prot values ( 18 ,"MUX");
insert into t_ip_prot values ( 19 ,"DCN-MEAS");
insert into t_ip_prot values ( 20 ,"HMP");
insert into t_ip_prot values ( 21 ,"PRM");
insert into t_ip_prot values ( 22 ,"XNS-IDP");
insert into t_ip_prot values ( 23 ,"TRUNK-1");
insert into t_ip_prot values ( 24 ,"TRUNK-2");
insert into t_ip_prot values ( 25 ,"LEAF-1");
insert into t_ip_prot values ( 26 ,"LEAF-2");
insert into t_ip_prot values ( 27 ,"RDP");
insert into t_ip_prot values ( 28 ,"IRTP");
insert into t_ip_prot values ( 29 ,"ISO-TP4");
insert into t_ip_prot values ( 30 ,"NETBLT");
insert into t_ip_prot values ( 31 ,"MFE-NSP");
insert into t_ip_prot values ( 32 ,"MERIT-INP");
insert into t_ip_prot values ( 33 ,"DCCP");
insert into t_ip_prot values ( 34 ,"3PC");
insert into t_ip_prot values ( 35 ,"IDPR");
insert into t_ip_prot values ( 36 ,"XTP");
insert into t_ip_prot values ( 37 ,"DDP");
insert into t_ip_prot values ( 38 ,"IDPR-CMTP");
insert into t_ip_prot values ( 39 ,"TP++");
insert into t_ip_prot values ( 40 ,"IL");
insert into t_ip_prot values ( 41 ,"IPv6");
insert into t_ip_prot values ( 42 ,"SDRP");
insert into t_ip_prot values ( 43 ,"IPv6-Route");
insert into t_ip_prot values ( 44 ,"IPv6-Frag");
insert into t_ip_prot values ( 45 ,"IDRP");
insert into t_ip_prot values ( 46 ,"RSVP");
insert into t_ip_prot values ( 47 ,"GRE");
insert into t_ip_prot values ( 48 ,"DSR");
insert into t_ip_prot values ( 49 ,"BNA");
insert into t_ip_prot values ( 50 ,"ESP");
insert into t_ip_prot values ( 51 ,"AH");
insert into t_ip_prot values ( 52 ,"I-NLSP");
insert into t_ip_prot values ( 53 ,"SwIPe");
insert into t_ip_prot values ( 54 ,"NARP");
insert into t_ip_prot values ( 55 ,"MOBILE");
insert into t_ip_prot values ( 56 ,"TLSP");
insert into t_ip_prot values ( 57 ,"SKIP");
insert into t_ip_prot values ( 58 ,"IPv6-ICMP");
insert into t_ip_prot values ( 59 ,"IPv6-NoNxt");
insert into t_ip_prot values ( 60 ,"IPv6-Opts");
insert into t_ip_prot values ( 61 ,"Any");
insert into t_ip_prot values ( 62 ,"CFTP");
insert into t_ip_prot values ( 63 ,"Any");
insert into t_ip_prot values ( 64 ,"SAT-EXPAK");
insert into t_ip_prot values ( 65 ,"KRYPTOLAN");
insert into t_ip_prot values ( 66 ,"RVD");
insert into t_ip_prot values ( 67 ,"IPPC");
insert into t_ip_prot values ( 68 ,"Any");
insert into t_ip_prot values ( 69 ,"SAT-MON");
insert into t_ip_prot values ( 70 ,"VISA");
insert into t_ip_prot values ( 71 ,"IPCU");
insert into t_ip_prot values ( 72 ,"CPNX");
insert into t_ip_prot values ( 73 ,"CPHB");
insert into t_ip_prot values ( 74 ,"WSN");
insert into t_ip_prot values ( 75 ,"PVP");
insert into t_ip_prot values ( 76 ,"BR-SAT-MON");
insert into t_ip_prot values ( 77 ,"SUN-ND");
insert into t_ip_prot values ( 78 ,"WB-MON");
insert into t_ip_prot values ( 79 ,"WB-EXPAK");
insert into t_ip_prot values ( 80 ,"ISO-IP");
insert into t_ip_prot values ( 81 ,"VMTP");
insert into t_ip_prot values ( 82 ,"SECURE-VMTP");
insert into t_ip_prot values ( 83 ,"VINES");
insert into t_ip_prot values ( 84 ,"IPTM");
insert into t_ip_prot values ( 85 ,"NSFNET-IGP");
insert into t_ip_prot values ( 86 ,"DGP");
insert into t_ip_prot values ( 87 ,"TCF");
insert into t_ip_prot values ( 88 ,"EIGRP");
insert into t_ip_prot values ( 89 ,"OSPF");
insert into t_ip_prot values ( 90 ,"Sprite-RPC");
insert into t_ip_prot values ( 91 ,"LARP");
insert into t_ip_prot values ( 92 ,"MTP");
insert into t_ip_prot values ( 93 ,"AX.25");
insert into t_ip_prot values ( 94 ,"OS");
insert into t_ip_prot values ( 95 ,"MICP");
insert into t_ip_prot values ( 96 ,"SCC-SP");
insert into t_ip_prot values ( 97 ,"ETHERIP");
insert into t_ip_prot values ( 98 ,"ENCAP");
insert into t_ip_prot values ( 99 ,"Any");
insert into t_ip_prot values ( 100 ,"GMTP");
insert into t_ip_prot values ( 101 ,"IFMP");
insert into t_ip_prot values ( 102 ,"PNNI");
insert into t_ip_prot values ( 103 ,"PIM");
insert into t_ip_prot values ( 104 ,"ARIS");
insert into t_ip_prot values ( 105 ,"SCPS");
insert into t_ip_prot values ( 106 ,"QNX");
insert into t_ip_prot values ( 107 ,"A/N");
insert into t_ip_prot values ( 108 ,"IPComp");
insert into t_ip_prot values ( 109 ,"SNP");
insert into t_ip_prot values ( 110 ,"Compaq-Peer");
insert into t_ip_prot values ( 111 ,"IPX-in-IP");
insert into t_ip_prot values ( 112 ,"VRRP");
insert into t_ip_prot values ( 113 ,"PGM");
insert into t_ip_prot values ( 114 ,"Any");
insert into t_ip_prot values ( 115 ,"L2TP");
insert into t_ip_prot values ( 116 ,"DDX");
insert into t_ip_prot values ( 117 ,"IATP");
insert into t_ip_prot values ( 118 ,"STP");
insert into t_ip_prot values ( 119 ,"SRP");
insert into t_ip_prot values ( 120 ,"UTI");
insert into t_ip_prot values ( 121 ,"SMP");
insert into t_ip_prot values ( 122 ,"SM");
insert into t_ip_prot values ( 123 ,"PTP");
insert into t_ip_prot values ( 124 ,"IS-IS");
insert into t_ip_prot values ( 125 ,"FIRE");
insert into t_ip_prot values ( 126 ,"CRTP");
insert into t_ip_prot values ( 127 ,"CRUDP");
insert into t_ip_prot values ( 128 ,"SSCOPMCE");
insert into t_ip_prot values ( 129 ,"IPLT");
insert into t_ip_prot values ( 130 ,"SPS");
insert into t_ip_prot values ( 131 ,"PIPE");
insert into t_ip_prot values ( 132 ,"SCTP");
insert into t_ip_prot values ( 133 ,"FC");
insert into t_ip_prot values ( 134 ,"RSVP-E2E-IGNORE");
insert into t_ip_prot values ( 135 ,"Mobility");
insert into t_ip_prot values ( 136 ,"UDPLite");
insert into t_ip_prot values ( 137 ,"MPLS-in-IP");
insert into t_ip_prot values ( 138 ,"manet");
insert into t_ip_prot values ( 139 ,"HIP");
insert into t_ip_prot values ( 140 ,"Shim6");
insert into t_ip_prot values ( 141 ,"WESP");
insert into t_ip_prot values ( 142 ,"ROHC");
insert into t_ip_prot values ( 143 ,"Ethernet");
insert into t_ip_prot values ( 144 ,"AGGFRAG");
insert into t_ip_prot values ( 145 ,"NSH");
insert into t_ip_prot values ( 146 ,"undefine");
insert into t_ip_prot values ( 147 ,"undefine");
insert into t_ip_prot values ( 148 ,"undefine");
insert into t_ip_prot values ( 149 ,"undefine");
insert into t_ip_prot values ( 150 ,"undefine");
insert into t_ip_prot values ( 151 ,"undefine");
insert into t_ip_prot values ( 152 ,"undefine");
insert into t_ip_prot values ( 153 ,"undefine");
insert into t_ip_prot values ( 154 ,"undefine");
insert into t_ip_prot values ( 155 ,"undefine");
insert into t_ip_prot values ( 156 ,"undefine");
insert into t_ip_prot values ( 157 ,"undefine");
insert into t_ip_prot values ( 158 ,"undefine");
insert into t_ip_prot values ( 159 ,"undefine");
insert into t_ip_prot values ( 160 ,"undefine");
insert into t_ip_prot values ( 161 ,"undefine");
insert into t_ip_prot values ( 162 ,"undefine");
insert into t_ip_prot values ( 163 ,"undefine");
insert into t_ip_prot values ( 164 ,"undefine");
insert into t_ip_prot values ( 165 ,"undefine");
insert into t_ip_prot values ( 166 ,"undefine");
insert into t_ip_prot values ( 167 ,"undefine");
insert into t_ip_prot values ( 168 ,"undefine");
insert into t_ip_prot values ( 169 ,"undefine");
insert into t_ip_prot values ( 170 ,"undefine");
insert into t_ip_prot values ( 171 ,"undefine");
insert into t_ip_prot values ( 172 ,"undefine");
insert into t_ip_prot values ( 173 ,"undefine");
insert into t_ip_prot values ( 174 ,"undefine");
insert into t_ip_prot values ( 175 ,"undefine");
insert into t_ip_prot values ( 176 ,"undefine");
insert into t_ip_prot values ( 177 ,"undefine");
insert into t_ip_prot values ( 178 ,"undefine");
insert into t_ip_prot values ( 179 ,"undefine");
insert into t_ip_prot values ( 180 ,"undefine");
insert into t_ip_prot values ( 181 ,"undefine");
insert into t_ip_prot values ( 182 ,"undefine");
insert into t_ip_prot values ( 183 ,"undefine");
insert into t_ip_prot values ( 184 ,"undefine");
insert into t_ip_prot values ( 185 ,"undefine");
insert into t_ip_prot values ( 186 ,"undefine");
insert into t_ip_prot values ( 187 ,"undefine");
insert into t_ip_prot values ( 188 ,"undefine");
insert into t_ip_prot values ( 189 ,"undefine");
insert into t_ip_prot values ( 190 ,"undefine");
insert into t_ip_prot values ( 191 ,"undefine");
insert into t_ip_prot values ( 192 ,"undefine");
insert into t_ip_prot values ( 193 ,"undefine");
insert into t_ip_prot values ( 194 ,"undefine");
insert into t_ip_prot values ( 195 ,"undefine");
insert into t_ip_prot values ( 196 ,"undefine");
insert into t_ip_prot values ( 197 ,"undefine");
insert into t_ip_prot values ( 198 ,"undefine");
insert into t_ip_prot values ( 199 ,"undefine");
drop table IF EXISTS t_oob_prot;
CREATE TABLE t_oob_prot (id text, frame_format text );
insert into t_oob_prot values ( 2048 ,"Internet IP ( IPv4 )");
insert into t_oob_prot values ( 2054 ,"Address Resolution Protocol ( ARP )");
insert into t_oob_prot values ( 32821 ,"Reverse Address Resolution Protocol ( RARP )");
insert into t_oob_prot values ( 32859 ,"VMTP ( Versatile Message Transaction Protocol )");
insert into t_oob_prot values ( 32923 ,"AppleTalk ( EtherTalk )");
insert into t_oob_prot values ( 33011 ,"AppleTalk Address Resolution Porotocol ( AARP )");
insert into t_oob_prot values ( 33079 ,"IPX ( Novell Netware )");
insert into t_oob_prot values ( 33100 ,"SNMP over Ethernet");
insert into t_oob_prot values ( 33169 ,"NetBIOS/NetBEUI");
insert into t_oob_prot values ( 33149 ,"XTP");
insert into t_oob_prot values ( 34525 ,"IP version 6 ( IPv6 )");
insert into t_oob_prot values ( 34915 ,"PPPoE Discovery Stage");
insert into t_oob_prot values ( 34916 ,"PPPoE Session Stage");
insert into t_oob_prot values ( 36864 ,"Loopback ( Configuration Test Protocol )");
drop table IF EXISTS t_af_family;
CREATE TABLE t_af_family (id text, af_family text );
insert into t_af_family values ( 0 ,"AF_UNSPEC");
insert into t_af_family values ( 1 ,"AF_UNIX");
insert into t_af_family values ( 2 ,"AF_INET");
insert into t_af_family values ( 3 ,"AF_AX25");
insert into t_af_family values ( 4 ,"AF_IPX");
insert into t_af_family values ( 5 ,"AF_APPLETALK");
insert into t_af_family values ( 6 ,"AF_NETROM");
insert into t_af_family values ( 7 ,"AF_BRIDGE");
insert into t_af_family values ( 8 ,"AF_ATMPVC");
insert into t_af_family values ( 9 ,"AF_X25");
insert into t_af_family values ( 10 ,"AF_INET6");
insert into t_af_family values ( 11 ,"AF_ROSE");
insert into t_af_family values ( 12 ,"AF_DECnet");
insert into t_af_family values ( 13 ,"AF_NETBEUI");
insert into t_af_family values ( 14 ,"AF_SECURITY");
insert into t_af_family values ( 15 ,"AF_KEY");
insert into t_af_family values ( 16 ,"AF_NETLINK");
insert into t_af_family values ( 17 ,"AF_PACKET");
insert into t_af_family values ( 18 ,"AF_ASH");
insert into t_af_family values ( 19 ,"AF_ECONET");
insert into t_af_family values ( 20 ,"AF_ATMSVC");
insert into t_af_family values ( 21 ,"AF_RDS");
insert into t_af_family values ( 22 ,"AF_SNA");
insert into t_af_family values ( 23 ,"AF_IRDA");
insert into t_af_family values ( 24 ,"AF_PPPOX");
insert into t_af_family values ( 25 ,"AF_WANPIPE");
insert into t_af_family values ( 26 ,"AF_LLC");
insert into t_af_family values ( 27 ,"AF_IB");
insert into t_af_family values ( 28 ,"AF_MPLS");
insert into t_af_family values ( 29 ,"AF_CAN");
insert into t_af_family values ( 30 ,"AF_TIPC");
insert into t_af_family values ( 31 ,"AF_BLUETOOTH");
insert into t_af_family values ( 32 ,"AF_IUCV");
insert into t_af_family values ( 33 ,"AF_RXRPC");
insert into t_af_family values ( 34 ,"AF_ISDN");
insert into t_af_family values ( 35 ,"AF_PHONET");
insert into t_af_family values ( 36 ,"AF_IEEE802154");
insert into t_af_family values ( 37 ,"AF_CAIF");
insert into t_af_family values ( 38 ,"AF_ALG");
insert into t_af_family values ( 39 ,"AF_NFC");
insert into t_af_family values ( 40 ,"AF_VSOCK");
insert into t_af_family values ( 41 ,"AF_KCM");
insert into t_af_family values ( 42 ,"AF_QIPCRTR");
insert into t_af_family values ( 43 ,"AF_SMC");
insert into t_af_family values ( 44 ,"AF_XDP");
insert into t_af_family values ( 45 ,"AF_MCTP");
drop table IF EXISTS t_icmpv6_typ;
CREATE TABLE t_icmpv6_typ (id int unsigned, icmp_type6 text );
insert into t_icmpv6_typ values ( 1 ,"Destination Unreachable");
insert into t_icmpv6_typ values ( 2 ,"Packet too Big");
insert into t_icmpv6_typ values ( 3 ,"Time Exceeded");
insert into t_icmpv6_typ values ( 4 ,"Parameter Problem");
insert into t_icmpv6_typ values ( 128 ,"Echo Request");
insert into t_icmpv6_typ values ( 129 ,"Echo Reply");
insert into t_icmpv6_typ values ( 130 ,"Multicast Listener Query");
insert into t_icmpv6_typ values ( 131 ,"Multicast Listener Report");
insert into t_icmpv6_typ values ( 132 ,"Multicast Listener Done");
insert into t_icmpv6_typ values ( 133 ,"Router Solicitation");
insert into t_icmpv6_typ values ( 134 ,"Router Advertisement");
insert into t_icmpv6_typ values ( 135 ,"Neighbor Solicitation");
insert into t_icmpv6_typ values ( 136 ,"Neighbor Advertisement");
insert into t_icmpv6_typ values ( 137 ,"Redirect");
..
DROP文以外はsqlite3用の内容と同じ。
IDの参照 項目名 テーブル作成。
$ mysql -u mulogd -p nulog < sqlm.sql
ULOGD2設定。
$ sudo nano /etc/ulogd.conf
...
[global]
logfile="syslog"
loglevel=3
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_inppkt_NFLOG.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_inppkt_ULOG.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_inppkt_UNIXSOCK.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_inpflow_NFCT.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_filter_IFINDEX.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_filter_IP2STR.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_filter_IP2BIN.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_filter_IP2HBIN.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_filter_PRINTPKT.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_filter_HWHDR.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_filter_PRINTFLOW.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_filter_MARK.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_output_LOGEMU.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_output_SYSLOG.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_output_GPRINT.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_output_NACCT.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_output_MYSQL.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_raw2packet_BASE.so"
stack=log2:NFLOG,base1:BASE,ifi1:IFINDEX,ip2bin1:IP2BIN,mac2str1:HWHDR,mysql1:MYSQL
[log2]
group=1 # Group has to be different from the one use in log1
[mysql1]
db="nulog"
host="localhost"
user="mulogd"
table="ulog"
pass="mulogdpp"
procedure="INSERT_PACKET_FULL"
...
上記の行がコメントになっていないこと。上の内容を修正・追加する。
ファイアーウォール設定。
$ nano nftables.sh
...
#!/bin/sh
echo "[NFTABLES.SH] **** start ****" > /dev/kmsg
# === initial ===
nft flush ruleset
# === ipv6 initial ===
nft add table ip6 filter6
nft add chain ip6 filter6 INPUT { type filter hook input priority 0 \; policy drop \; }
nft add chain ip6 filter6 FORWARD { type filter hook forward priority 0 \; policy drop \; }
nft add chain ip6 filter6 OUTPUT { type filter hook output priority 0 \; policy accept \; }
nft add chain ip6 filter6 POSTROUTING { type nat hook postrouting priority 100 \; policy drop \; }
nft add rule ip6 filter6 POSTROUTING log prefix \"[IPV6 POSTROUTE]\" group 1
nft add rule ip6 filter6 POSTROUTING drop
nft add rule ip6 filter6 FORWARD log prefix \"[IPV6 FORWARD]\" group 1
nft add rule ip6 filter6 FORWARD drop
nft add rule ip6 filter6 INPUT log prefix \"[IPV6 INPUT]\" group 1
nft add rule ip6 filter6 INPUT drop
# === ipv4 initial ===
nft add table ip setwall
nft add chain ip setwall input { type filter hook input priority 0 \; policy drop \; }
nft add chain ip setwall forward { type filter hook forward priority 0 \; policy drop \; }
nft add chain ip setwall output { type filter hook output priority 0 \; policy accept \; }
nft add chain ip setwall callsub
# === ipv4 set input wall ===
nft add rule ip setwall input iifname lo accept
nft add rule ip setwall input iif eth0 ct state { established, related } accept
nft add rule ip setwall input iif wlan0 ct state { established, related } accept
nft add rule ip setwall input ct state invalid drop
#
nft add rule ip setwall input ip saddr 192.168.0.0/16 tcp dport {22, 8080} jump callsub
nft add rule ip setwall input log prefix \"[DROP]\" group 1
# --- call sub
nft add rule ip setwall callsub log prefix \"[INPUT]\" group 1 accept
# ... END ...
...
各チェーンごとにlogでパケットを確認する場合に入れる。
行右端にあるgroup 2は、/etc/ulogd.confのstack=log2:NFLOG,base1:BASE,i.... で定義した[log2]に
書いたgroupの数字と同じものを指定。番号があっていないとログはDBに入らない。
$ chmod +x nftables.sh
$ sudo ./nftables.sh
ファイアーウォール設定
ULOGD2 再起動。
$ sudo systemctl restart ulogd
$ sudo systemctl status ulogd
動作確認、エラーが出てないこと。
動作確認。
$ python -m http.server 8080
他のPCで。
$ curl http://192.168.x.xx:8080
Mysql検出結果表示。
$ nano sel2.sql
...
$ cat sel2.sql
SELECT " DateTime","prefix","in-if","mac_saddr","saddr","out-if","mac_daddr","daddr","af_family","udp_sport","udp_dport","header_prot","tcp_dport" UNION select from_unixtime(oob_time_sec) as DateTime,oob_prefix,oob_in,mac_saddr_str,INET6_NTOA(ip_saddr_bin) as saddr,oob_out,mac_daddr_str, INET6_NTOA(ip_daddr_bin)as daddr,t_af_family.af_family, udp_sport, udp_dport,t_ip_prot.header_prot,tcp_dport from ulog left outer join t_ip_prot on ulog.ip_protocol = t_ip_prot.id left outer join t_af_family on ulog.oob_family = t_af_family.id order by DateTime into outfile "/tmp/sample.csv" FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ;
...
1行で書く。
最初のselect の" DateTime"の空白は日付数字よりコードが小さいことで入れた。order by DateTime の処理のため。
into outfile "/tmp/sample.csv"は書き込みユーザがmysqlなので"/tmp"に書き込む。
mariadb(MYSQL)に書き込まれたデータの確認。
$ mysql -u mulogd -p nulog < sel2.sql
$ cp /tmp/sample.csv .
UIDが自分になる
$ sudo rm /tmp/sample.csv
ファイル削除
$ cat sample.csv
...
" DateTime","prefix","in-if","mac_saddr","saddr","out-if","mac_daddr","daddr","af_family","udp_sport","udp_dport","header_prot","tcp_dport"
"2025-03-10 22:49:07","[DROP]","eth0","xx:xx:xx:xx:5d:31","::ffff:192.168.1.xx","","xx:xx:xx:xx:00:fb","::ffff:224.0.0.251","AF_INET","5353","5353","UDP",\N
"2025-03-10 22:56:17","[INPUT]","eth0","xx:xx:xx:xx:44:a1","::ffff:192.168.1.x","","xx:xx:xx:xx:b6:5f","::ffff:192.168.1.x","AF_INET",\N,\N,"TCP","8080"
"2025-03-10 23:00:21","[DROP]","eth0","xx:xx:xx:xx:5d:31","::ffff:192.168.1.xx","","xx:xx:xx:xx:00:fb","::ffff:224.0.0.251","AF_INET","5353","5353","UDP",\N
...
参考:
https://stackoverflow.com/questions/13552206/grant-file-on-just-one-database
`GRANT FILE ON` just one database
https://dba.stackexchange.com/questions/17029/cannot-output-mysql-data-to-file
Cannot output MySQL data to file
https://forums.mysql.com/read.php?10,698113,698116#msg-698116
Re: Export table to csv with column headers
2025-02-27 「NFT -> LOG -> ulogd2 -> SQLITE3 db」
NFTABLEのログをSQLITE3データベースに書き込んでみた。
(1) db インストール
$ sudo apt install sqlite3
$ sudo apt install ulogd2 ulogd2-sqlite3
ulogd2をインストールすると以下がインストールされる。
$ ls -l /usr/share/doc/ulogd2
合計 100
-rw-r--r-- 1 root root 106 11月 2 2022 AUTHORS
-rw-r--r-- 1 root root 388 12月 30 2022 NEWS.Debian.gz
-rw-r--r-- 1 root root 3387 11月 2 2022 README
-rw-r--r-- 1 root root 1304 12月 30 2022 README.Debian
-rw-r--r-- 1 root root 190 11月 2 2022 TODO
-rw-r--r-- 1 root root 1826 12月 30 2022 changelog.Debian.gz
-rw-r--r-- 1 root root 2757 12月 30 2022 copyright
drwxr-xr-x 2 root root 4096 2月 24 23:02 examples
-rw-r--r-- 1 root root 3399 11月 2 2022 mysql-ulogd2-flat.sql.gz
-rw-r--r-- 1 root root 6517 11月 2 2022 mysql-ulogd2.sql.gz
-rw-r--r-- 1 root root 2767 11月 2 2022 pgsql-ulogd2-flat.sql.gz
-rw-r--r-- 1 root root 5179 11月 2 2022 pgsql-ulogd2.sql.gz
-rw-r--r-- 1 root root 854 11月 2 2022 sqlite3.table
-rw-r--r-- 1 root root 25990 12月 30 2022 ulogd.html
-rw-r--r-- 1 root root 8790 12月 30 2022 ulogd.txt.gz
...
参照:
https://gist.github.com/AlexanderARodin/5adc9113a03642857ad2b459a7ecb825
AlexanderARodin/ulogd2-sqlite3.md
$ sudo cp /etc/ulogd.conf /etc/ulogd-org.conf
$ sudo nano /etc/ulogd.conf
...
[global]
logfile="syslog"
loglevel=3
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_inppkt_NFLOG.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_inppkt_ULOG.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_inppkt_UNIXSOCK.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_inpflow_NFCT.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_filter_IFINDEX.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_filter_IP2STR.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_filter_IP2BIN.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_filter_IP2HBIN.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_filter_PRINTPKT.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_filter_HWHDR.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_filter_PRINTFLOW.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_filter_MARK.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_output_LOGEMU.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_output_SYSLOG.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_output_SQLITE3.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_output_GPRINT.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_output_NACCT.so"
plugin="/usr/lib/aarch64-linux-gnu/ulogd/ulogd_raw2packet_BASE.so"
stack=log3:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,mac2str1:HWHDR,boot_sqlt:SQLITE3
[log3]
group=2 # Group has to be different from the one use in log1/log2
[boot_sqlt]
table="all_in"
db="/var/log/ulog/ulogd_sqlite3.db"
...
上記の行がコメントになっていないこと。上の内容を修正・追加する。
$ cat ulogd.conf | sed -e "s/^#.*$//g" -e '/^ *$/d'
SQLITE3データベースの作成。
列の項目がコードなので見やすくするためのコードの名前を表示するために紐付けるテーブルも作成。
$ nano sql3.sql
...
DROP TABLE all_in;
CREATE TABLE all_in (
oob_prefix TEXT,
oob_time_sec INT UNSIGNED,
oob_time_usec INT UNSIGNED,
oob_uid INT UNSIGNED,
oob_protocol TEXT,
oob_family TEXT,
ip_protocol INT UNSIGNED,
ip_tos INT UNSIGNED,
ip_ttl INT UNSIGNED,
ip_totlen INT UNSIGNED,
ip_ihl INT UNSIGNED,
ip_csum INT UNSIGNED,
ip_id INT UNSIGNED,
ip_fragoff INT UNSIGNED,
ip6_payloadlen INT UNSIGNED,
ip6_priority INT UNSIGNED,
ip6_flowlabel INT UNSIGNED,
ip6_hoplimit INT UNSIGNED,
ip6_nexthdr INT UNSIGNED,
ip6_fragoff INT UNSIGNED,
ip6_fragid INT UNSIGNED,
tcp_sport INT UNSIGNED,
tcp_dport INT UNSIGNED,
tcp_seq INT UNSIGNED,
tcp_ackseq INT UNSIGNED,
tcp_window INT UNSIGNED,
tcp_offset INT UNSIGNED,
tcp_reserved INT UNSIGNED,
tcp_urg INT UNSIGNED,
tcp_urgp INT UNSIGNED,
tcp_ack INT UNSIGNED,
tcp_psh INT UNSIGNED,
tcp_rst INT UNSIGNED,
tcp_syn INT UNSIGNED,
tcp_fin INT UNSIGNED,
tcp_res1 INT UNSIGNED,
tcp_res2 INT UNSIGNED,
tcp_csum INT UNSIGNED,
udp_sport INT UNSIGNED,
udp_dport INT UNSIGNED,
udp_len INT UNSIGNED,
udp_csum INT UNSIGNED,
icmp_type INT UNSIGNED,
icmp_code INT UNSIGNED,
icmp_echoid INT UNSIGNED,
icmp_echoseq INT UNSIGNED,
icmp_fragmtu INT UNSIGNED,
icmp_csum INT UNSIGNED,
icmpv6_type INT UNSIGNED,
icmpv6_code INT UNSIGNED,
icmpv6_echoid INT UNSIGNED,
icmpv6_echoseq INT UNSIGNED,
icmpv6_csum INT UNSIGNED,
ahesp_spi INT UNSIGNED,
arp_hwtype INT UNSIGNED,
arp_protocoltype INT UNSIGNED,
arp_operation INT UNSIGNED,
sctp_sport INT UNSIGNED,
sctp_dport INT UNSIGNED,
sctp_csum INT UNSIGNED,
oob_in TEXT,
oob_out TEXT,
mac_saddr_str TEXT,
mac_daddr_str TEXT,
ip_saddr_str TEXT,
ip_daddr_str TEXT,
orig_ip_saddr_str TEXT,
orig_ip_daddr_str TEXT,
reply_ip_saddr_str TEXT,
reply_ip_daddr_str TEXT,
arp_saddr_str TEXT,
arp_daddr_str TEXT,
PRIMARY KEY ( oob_time_sec, oob_time_usec )
);
drop table t_ip_prot;
CREATE TABLE t_ip_prot (id int unsigned, header_prot text );
insert into t_ip_prot values ( 0 ,"HOPOPT");
insert into t_ip_prot values ( 1 ,"ICMP");
insert into t_ip_prot values ( 2 ,"IGMP");
insert into t_ip_prot values ( 3 ,"GGP");
insert into t_ip_prot values ( 4 ,"IP-in-IP");
insert into t_ip_prot values ( 5 ,"ST");
insert into t_ip_prot values ( 6 ,"TCP");
insert into t_ip_prot values ( 7 ,"CBT");
insert into t_ip_prot values ( 8 ,"EGP");
insert into t_ip_prot values ( 9 ,"IGP");
insert into t_ip_prot values ( 10 ,"BBN-RCC-MON");
insert into t_ip_prot values ( 11 ,"NVP-II");
insert into t_ip_prot values ( 12 ,"PUP");
insert into t_ip_prot values ( 13 ,"ARGUS");
insert into t_ip_prot values ( 14 ,"EMCON");
insert into t_ip_prot values ( 15 ,"XNET");
insert into t_ip_prot values ( 16 ,"CHAOS");
insert into t_ip_prot values ( 17 ,"UDP");
insert into t_ip_prot values ( 18 ,"MUX");
insert into t_ip_prot values ( 19 ,"DCN-MEAS");
insert into t_ip_prot values ( 20 ,"HMP");
insert into t_ip_prot values ( 21 ,"PRM");
insert into t_ip_prot values ( 22 ,"XNS-IDP");
insert into t_ip_prot values ( 23 ,"TRUNK-1");
insert into t_ip_prot values ( 24 ,"TRUNK-2");
insert into t_ip_prot values ( 25 ,"LEAF-1");
insert into t_ip_prot values ( 26 ,"LEAF-2");
insert into t_ip_prot values ( 27 ,"RDP");
insert into t_ip_prot values ( 28 ,"IRTP");
insert into t_ip_prot values ( 29 ,"ISO-TP4");
insert into t_ip_prot values ( 30 ,"NETBLT");
insert into t_ip_prot values ( 31 ,"MFE-NSP");
insert into t_ip_prot values ( 32 ,"MERIT-INP");
insert into t_ip_prot values ( 33 ,"DCCP");
insert into t_ip_prot values ( 34 ,"3PC");
insert into t_ip_prot values ( 35 ,"IDPR");
insert into t_ip_prot values ( 36 ,"XTP");
insert into t_ip_prot values ( 37 ,"DDP");
insert into t_ip_prot values ( 38 ,"IDPR-CMTP");
insert into t_ip_prot values ( 39 ,"TP++");
insert into t_ip_prot values ( 40 ,"IL");
insert into t_ip_prot values ( 41 ,"IPv6");
insert into t_ip_prot values ( 42 ,"SDRP");
insert into t_ip_prot values ( 43 ,"IPv6-Route");
insert into t_ip_prot values ( 44 ,"IPv6-Frag");
insert into t_ip_prot values ( 45 ,"IDRP");
insert into t_ip_prot values ( 46 ,"RSVP");
insert into t_ip_prot values ( 47 ,"GRE");
insert into t_ip_prot values ( 48 ,"DSR");
insert into t_ip_prot values ( 49 ,"BNA");
insert into t_ip_prot values ( 50 ,"ESP");
insert into t_ip_prot values ( 51 ,"AH");
insert into t_ip_prot values ( 52 ,"I-NLSP");
insert into t_ip_prot values ( 53 ,"SwIPe");
insert into t_ip_prot values ( 54 ,"NARP");
insert into t_ip_prot values ( 55 ,"MOBILE");
insert into t_ip_prot values ( 56 ,"TLSP");
insert into t_ip_prot values ( 57 ,"SKIP");
insert into t_ip_prot values ( 58 ,"IPv6-ICMP");
insert into t_ip_prot values ( 59 ,"IPv6-NoNxt");
insert into t_ip_prot values ( 60 ,"IPv6-Opts");
insert into t_ip_prot values ( 61 ,"Any");
insert into t_ip_prot values ( 62 ,"CFTP");
insert into t_ip_prot values ( 63 ,"Any");
insert into t_ip_prot values ( 64 ,"SAT-EXPAK");
insert into t_ip_prot values ( 65 ,"KRYPTOLAN");
insert into t_ip_prot values ( 66 ,"RVD");
insert into t_ip_prot values ( 67 ,"IPPC");
insert into t_ip_prot values ( 68 ,"Any");
insert into t_ip_prot values ( 69 ,"SAT-MON");
insert into t_ip_prot values ( 70 ,"VISA");
insert into t_ip_prot values ( 71 ,"IPCU");
insert into t_ip_prot values ( 72 ,"CPNX");
insert into t_ip_prot values ( 73 ,"CPHB");
insert into t_ip_prot values ( 74 ,"WSN");
insert into t_ip_prot values ( 75 ,"PVP");
insert into t_ip_prot values ( 76 ,"BR-SAT-MON");
insert into t_ip_prot values ( 77 ,"SUN-ND");
insert into t_ip_prot values ( 78 ,"WB-MON");
insert into t_ip_prot values ( 79 ,"WB-EXPAK");
insert into t_ip_prot values ( 80 ,"ISO-IP");
insert into t_ip_prot values ( 81 ,"VMTP");
insert into t_ip_prot values ( 82 ,"SECURE-VMTP");
insert into t_ip_prot values ( 83 ,"VINES");
insert into t_ip_prot values ( 84 ,"IPTM");
insert into t_ip_prot values ( 85 ,"NSFNET-IGP");
insert into t_ip_prot values ( 86 ,"DGP");
insert into t_ip_prot values ( 87 ,"TCF");
insert into t_ip_prot values ( 88 ,"EIGRP");
insert into t_ip_prot values ( 89 ,"OSPF");
insert into t_ip_prot values ( 90 ,"Sprite-RPC");
insert into t_ip_prot values ( 91 ,"LARP");
insert into t_ip_prot values ( 92 ,"MTP");
insert into t_ip_prot values ( 93 ,"AX.25");
insert into t_ip_prot values ( 94 ,"OS");
insert into t_ip_prot values ( 95 ,"MICP");
insert into t_ip_prot values ( 96 ,"SCC-SP");
insert into t_ip_prot values ( 97 ,"ETHERIP");
insert into t_ip_prot values ( 98 ,"ENCAP");
insert into t_ip_prot values ( 99 ,"Any");
insert into t_ip_prot values ( 100 ,"GMTP");
insert into t_ip_prot values ( 101 ,"IFMP");
insert into t_ip_prot values ( 102 ,"PNNI");
insert into t_ip_prot values ( 103 ,"PIM");
insert into t_ip_prot values ( 104 ,"ARIS");
insert into t_ip_prot values ( 105 ,"SCPS");
insert into t_ip_prot values ( 106 ,"QNX");
insert into t_ip_prot values ( 107 ,"A/N");
insert into t_ip_prot values ( 108 ,"IPComp");
insert into t_ip_prot values ( 109 ,"SNP");
insert into t_ip_prot values ( 110 ,"Compaq-Peer");
insert into t_ip_prot values ( 111 ,"IPX-in-IP");
insert into t_ip_prot values ( 112 ,"VRRP");
insert into t_ip_prot values ( 113 ,"PGM");
insert into t_ip_prot values ( 114 ,"Any");
insert into t_ip_prot values ( 115 ,"L2TP");
insert into t_ip_prot values ( 116 ,"DDX");
insert into t_ip_prot values ( 117 ,"IATP");
insert into t_ip_prot values ( 118 ,"STP");
insert into t_ip_prot values ( 119 ,"SRP");
insert into t_ip_prot values ( 120 ,"UTI");
insert into t_ip_prot values ( 121 ,"SMP");
insert into t_ip_prot values ( 122 ,"SM");
insert into t_ip_prot values ( 123 ,"PTP");
insert into t_ip_prot values ( 124 ,"IS-IS");
insert into t_ip_prot values ( 125 ,"FIRE");
insert into t_ip_prot values ( 126 ,"CRTP");
insert into t_ip_prot values ( 127 ,"CRUDP");
insert into t_ip_prot values ( 128 ,"SSCOPMCE");
insert into t_ip_prot values ( 129 ,"IPLT");
insert into t_ip_prot values ( 130 ,"SPS");
insert into t_ip_prot values ( 131 ,"PIPE");
insert into t_ip_prot values ( 132 ,"SCTP");
insert into t_ip_prot values ( 133 ,"FC");
insert into t_ip_prot values ( 134 ,"RSVP-E2E-IGNORE");
insert into t_ip_prot values ( 135 ,"Mobility");
insert into t_ip_prot values ( 136 ,"UDPLite");
insert into t_ip_prot values ( 137 ,"MPLS-in-IP");
insert into t_ip_prot values ( 138 ,"manet");
insert into t_ip_prot values ( 139 ,"HIP");
insert into t_ip_prot values ( 140 ,"Shim6");
insert into t_ip_prot values ( 141 ,"WESP");
insert into t_ip_prot values ( 142 ,"ROHC");
insert into t_ip_prot values ( 143 ,"Ethernet");
insert into t_ip_prot values ( 144 ,"AGGFRAG");
insert into t_ip_prot values ( 145 ,"NSH");
insert into t_ip_prot values ( 146 ,"undefine");
insert into t_ip_prot values ( 147 ,"undefine");
insert into t_ip_prot values ( 148 ,"undefine");
insert into t_ip_prot values ( 149 ,"undefine");
insert into t_ip_prot values ( 150 ,"undefine");
insert into t_ip_prot values ( 151 ,"undefine");
insert into t_ip_prot values ( 152 ,"undefine");
insert into t_ip_prot values ( 153 ,"undefine");
insert into t_ip_prot values ( 154 ,"undefine");
insert into t_ip_prot values ( 155 ,"undefine");
insert into t_ip_prot values ( 156 ,"undefine");
insert into t_ip_prot values ( 157 ,"undefine");
insert into t_ip_prot values ( 158 ,"undefine");
insert into t_ip_prot values ( 159 ,"undefine");
insert into t_ip_prot values ( 160 ,"undefine");
insert into t_ip_prot values ( 161 ,"undefine");
insert into t_ip_prot values ( 162 ,"undefine");
insert into t_ip_prot values ( 163 ,"undefine");
insert into t_ip_prot values ( 164 ,"undefine");
insert into t_ip_prot values ( 165 ,"undefine");
insert into t_ip_prot values ( 166 ,"undefine");
insert into t_ip_prot values ( 167 ,"undefine");
insert into t_ip_prot values ( 168 ,"undefine");
insert into t_ip_prot values ( 169 ,"undefine");
insert into t_ip_prot values ( 170 ,"undefine");
insert into t_ip_prot values ( 171 ,"undefine");
insert into t_ip_prot values ( 172 ,"undefine");
insert into t_ip_prot values ( 173 ,"undefine");
insert into t_ip_prot values ( 174 ,"undefine");
insert into t_ip_prot values ( 175 ,"undefine");
insert into t_ip_prot values ( 176 ,"undefine");
insert into t_ip_prot values ( 177 ,"undefine");
insert into t_ip_prot values ( 178 ,"undefine");
insert into t_ip_prot values ( 179 ,"undefine");
insert into t_ip_prot values ( 180 ,"undefine");
insert into t_ip_prot values ( 181 ,"undefine");
insert into t_ip_prot values ( 182 ,"undefine");
insert into t_ip_prot values ( 183 ,"undefine");
insert into t_ip_prot values ( 184 ,"undefine");
insert into t_ip_prot values ( 185 ,"undefine");
insert into t_ip_prot values ( 186 ,"undefine");
insert into t_ip_prot values ( 187 ,"undefine");
insert into t_ip_prot values ( 188 ,"undefine");
insert into t_ip_prot values ( 189 ,"undefine");
insert into t_ip_prot values ( 190 ,"undefine");
insert into t_ip_prot values ( 191 ,"undefine");
insert into t_ip_prot values ( 192 ,"undefine");
insert into t_ip_prot values ( 193 ,"undefine");
insert into t_ip_prot values ( 194 ,"undefine");
insert into t_ip_prot values ( 195 ,"undefine");
insert into t_ip_prot values ( 196 ,"undefine");
insert into t_ip_prot values ( 197 ,"undefine");
insert into t_ip_prot values ( 198 ,"undefine");
insert into t_ip_prot values ( 199 ,"undefine");
drop table t_oob_prot;
CREATE TABLE t_oob_prot (id text, frame_format text );
insert into t_oob_prot values ( 2048 ,"Internet IP ( IPv4 )");
insert into t_oob_prot values ( 2054 ,"Address Resolution Protocol ( ARP )");
insert into t_oob_prot values ( 32821 ,"Reverse Address Resolution Protocol ( RARP )");
insert into t_oob_prot values ( 32859 ,"VMTP ( Versatile Message Transaction Protocol )");
insert into t_oob_prot values ( 32923 ,"AppleTalk ( EtherTalk )");
insert into t_oob_prot values ( 33011 ,"AppleTalk Address Resolution Porotocol ( AARP )");
insert into t_oob_prot values ( 33079 ,"IPX ( Novell Netware )");
insert into t_oob_prot values ( 33100 ,"SNMP over Ethernet");
insert into t_oob_prot values ( 33169 ,"NetBIOS/NetBEUI");
insert into t_oob_prot values ( 33149 ,"XTP");
insert into t_oob_prot values ( 34525 ,"IP version 6 ( IPv6 )");
insert into t_oob_prot values ( 34915 ,"PPPoE Discovery Stage");
insert into t_oob_prot values ( 34916 ,"PPPoE Session Stage");
insert into t_oob_prot values ( 36864 ,"Loopback ( Configuration Test Protocol )");
drop table t_af_family;
CREATE TABLE t_af_family (id text, af_family text );
insert into t_af_family values ( 0 ,"AF_UNSPEC");
insert into t_af_family values ( 1 ,"AF_UNIX");
insert into t_af_family values ( 2 ,"AF_INET");
insert into t_af_family values ( 3 ,"AF_AX25");
insert into t_af_family values ( 4 ,"AF_IPX");
insert into t_af_family values ( 5 ,"AF_APPLETALK");
insert into t_af_family values ( 6 ,"AF_NETROM");
insert into t_af_family values ( 7 ,"AF_BRIDGE");
insert into t_af_family values ( 8 ,"AF_ATMPVC");
insert into t_af_family values ( 9 ,"AF_X25");
insert into t_af_family values ( 10 ,"AF_INET6");
insert into t_af_family values ( 11 ,"AF_ROSE");
insert into t_af_family values ( 12 ,"AF_DECnet");
insert into t_af_family values ( 13 ,"AF_NETBEUI");
insert into t_af_family values ( 14 ,"AF_SECURITY");
insert into t_af_family values ( 15 ,"AF_KEY");
insert into t_af_family values ( 16 ,"AF_NETLINK");
insert into t_af_family values ( 17 ,"AF_PACKET");
insert into t_af_family values ( 18 ,"AF_ASH");
insert into t_af_family values ( 19 ,"AF_ECONET");
insert into t_af_family values ( 20 ,"AF_ATMSVC");
insert into t_af_family values ( 21 ,"AF_RDS");
insert into t_af_family values ( 22 ,"AF_SNA");
insert into t_af_family values ( 23 ,"AF_IRDA");
insert into t_af_family values ( 24 ,"AF_PPPOX");
insert into t_af_family values ( 25 ,"AF_WANPIPE");
insert into t_af_family values ( 26 ,"AF_LLC");
insert into t_af_family values ( 27 ,"AF_IB");
insert into t_af_family values ( 28 ,"AF_MPLS");
insert into t_af_family values ( 29 ,"AF_CAN");
insert into t_af_family values ( 30 ,"AF_TIPC");
insert into t_af_family values ( 31 ,"AF_BLUETOOTH");
insert into t_af_family values ( 32 ,"AF_IUCV");
insert into t_af_family values ( 33 ,"AF_RXRPC");
insert into t_af_family values ( 34 ,"AF_ISDN");
insert into t_af_family values ( 35 ,"AF_PHONET");
insert into t_af_family values ( 36 ,"AF_IEEE802154");
insert into t_af_family values ( 37 ,"AF_CAIF");
insert into t_af_family values ( 38 ,"AF_ALG");
insert into t_af_family values ( 39 ,"AF_NFC");
insert into t_af_family values ( 40 ,"AF_VSOCK");
insert into t_af_family values ( 41 ,"AF_KCM");
insert into t_af_family values ( 42 ,"AF_QIPCRTR");
insert into t_af_family values ( 43 ,"AF_SMC");
insert into t_af_family values ( 44 ,"AF_XDP");
insert into t_af_family values ( 45 ,"AF_MCTP");
drop table t_icmpv6_typ;
CREATE TABLE t_icmpv6_typ (id int unsigned, icmp_type6 text );
insert into t_icmpv6_typ values ( 1 ,"Destination Unreachable");
insert into t_icmpv6_typ values ( 2 ,"Packet too Big");
insert into t_icmpv6_typ values ( 3 ,"Time Exceeded");
insert into t_icmpv6_typ values ( 4 ,"Parameter Problem");
insert into t_icmpv6_typ values ( 128 ,"Echo Request");
insert into t_icmpv6_typ values ( 129 ,"Echo Reply");
insert into t_icmpv6_typ values ( 130 ,"Multicast Listener Query");
insert into t_icmpv6_typ values ( 131 ,"Multicast Listener Report");
insert into t_icmpv6_typ values ( 132 ,"Multicast Listener Done");
insert into t_icmpv6_typ values ( 133 ,"Router Solicitation");
insert into t_icmpv6_typ values ( 134 ,"Router Advertisement");
insert into t_icmpv6_typ values ( 135 ,"Neighbor Solicitation");
insert into t_icmpv6_typ values ( 136 ,"Neighbor Advertisement");
insert into t_icmpv6_typ values ( 137 ,"Redirect");
...
$ sudo sqlite3 /var/log/ulog/ulogd_sqlite3.db < sql3.sql
データベースは、ulogd.conf 「db="/var/log/ulog/ulogd_sqlite3.db"」で設定したもの。
$ sqlite3 /var/log/ulog/ulogd_sqlite3.db
all_in t_af_family t_icmpv6_typ t_ip_prot t_oob_prot
sqlite> .q
...
$ sudo systemctl restart ulogd2
$ sudo systemctl status ulogd2
確認
$ nano attach-ulogd.sh
...
#!/bin/sh
n=0
while [ $n -le 10 ]
do
sleep 1
ULOGD=`systemctl status ulogd | grep 'error'`
if [ "$ULOGD" = "" ]; then
echo "attached ulogd2"
break
fi
systemctl restart ulogd
n=`expr $n + 1`
done
if [ "$ULOGD" != "" ]; then
echo "ULOGD2 ??? Error"
fi
...
$ sudo chmod +x /etc/raspi/attach-ulogd.sh
rc.local追加
--- /etc/rc.local ---
#!/bin/sh -e
/home/pi/nftables.sh
/home/pi/attach-ulogd.sh &
exit 0
----
追加する。
ブート時、ulogd2が正常に動作しているかを確認・再起動をするもの。
$ nano nftables.sh
...
#!/bin/sh
echo "[NFTABLES.SH] **** start ****" > /dev/kmsg
# === initial ===
nft flush ruleset
# === ipv6 initial ===
nft add table ip6 filter6
nft add chain ip6 filter6 INPUT { type filter hook input priority 0 \; policy drop \; }
nft add chain ip6 filter6 FORWARD { type filter hook forward priority 0 \; policy drop \; }
nft add chain ip6 filter6 OUTPUT { type filter hook output priority 0 \; policy accept \; }
nft add chain ip6 filter6 POSTROUTING { type nat hook postrouting priority 100 \; policy drop \; }
nft add rule ip6 filter6 POSTROUTING log prefix \"[IPV6 POSTROUTE]\" group 2
nft add rule ip6 filter6 POSTROUTING drop
nft add rule ip6 filter6 FORWARD log prefix \"[IPV6 FORWARD]\" group 2
nft add rule ip6 filter6 FORWARD drop
nft add rule ip6 filter6 INPUT log prefix \"[IPV6 INPUT]\" group 2
nft add rule ip6 filter6 INPUT drop
# === ipv4 initial ===
nft add table ip setwall
nft add chain ip setwall input { type filter hook input priority 0 \; policy drop \; }
nft add chain ip setwall forward { type filter hook forward priority 0 \; policy drop \; }
nft add chain ip setwall output { type filter hook output priority 0 \; policy accept \; }
nft add chain ip setwall callsub
# === ipv4 set input wall ===
nft add rule ip setwall input iifname lo accept
nft add rule ip setwall input iif eth0 ct state { established, related } accept
nft add rule ip setwall input iif wlan0 ct state { established, related } accept
nft add rule ip setwall input ct state invalid drop
#
nft add rule ip setwall input ip saddr 192.168.0.0/16 tcp dport {22, 8080} jump callsub
nft add rule ip setwall input log prefix \"[DROP]\" group 2
# --- call sub
nft add rule ip setwall callsub log prefix \"[INPUT]\" group 2 accept
# ... END ...
...
各チェーンごとにlogでパケットを確認する場合に入れる。
行右端にあるgroup 2は、/etc/ulogd.confのstack=log3:NFLOG,base1:BASE,i.... で定義した[log3]に
書いたgroup=2の数字と同じものを指定。番号があっていないとログはDBに入らない。
$ chmod +x nftables.sh
$ sudo ./nftables.sh
ファイアーウォール設定
データベースを確認するためのPYTHONプログラム。
$ nano dblite.py
...
#!/usr/bin/python
# (c) K.Shimomura (The MIT License)
import datetime
import sqlite3
import sys
import warnings
import ip_socket_inf
# データベース パス
ip_dbname = "/var/log/ulog/ulogd_sqlite3.db"
# socket 情報格納テーブル名
ip_table = "all_in"
def main():
argv = sys.argv
if len(argv) < 2:
day_time = '2025-02-20 00:00:00'
else:
day_time = argv[1]
warnings.filterwarnings('ignore')
#f = open(sys.stdout, "w", "utf-8")
connect0 = sqlite3.connect(
ip_dbname
)
cursor = connect0.cursor()
ncolm = []
#cursor.execute("SELECT name FROM PRAGMA_TABLE_INFO('" + ip_table + "')")
#result = cursor.fetchall()
#for row in result:
# ncolm.append(row)
#print(ncolm)
#day_time = '2025-02-24 01:00:00'
#cursor.execute("select * from " + ip_table + " where datetime(oob_time_sec + 32400, 'unixepoch') > '" + day_time + "';")
cursor.execute("select oob_time_sec as date,oob_prefix, oob_protocol,ip_protocol,tcp_sport,tcp_dport,udp_sport,udp_dport,oob_in,oob_out,ip_saddr_str,ip_daddr_str from " + ip_table + " where datetime(oob_time_sec + 32400, 'unixepoch') > '" + day_time + "';")
desc = cursor.description
result = cursor.fetchall()
for row in result:
for n,i in enumerate(row):
if i != None:
if desc[n][0] == 'ip_protocol' and i < 200:
print("%s : %s / %s" % (desc[n][0] ,i,ip_socket_inf.ip_prot_t[i]))
elif desc[n][0] == 'icmpv6_type':
print("%s : %s / %s" % (desc[n][0] ,i,icmpv6_type[i]))
elif desc[n][0] == 'oob_family' and int(i) in ip_socket_inf.af_family:
print("%s : %s / %s" % (desc[n][0] ,i,ip_socket_inf.af_family[int(i)]))
elif desc[n][0] == 'date' or desc[n][0] == 'oob_time_sec':
print("%s : %s" % (desc[n][0] ,datetime.datetime.fromtimestamp(i)))
elif desc[n][0] == 'oob_protocol' and int(i) in ip_socket_inf.oob_prot_t:
print("%s : %s / %s" % (desc[n][0] ,i,ip_socket_inf.oob_prot_t[int(i)]))
elif desc[n][0] == 'oob_time_usec':
pass
else:
print("%s : %s" % (desc[n][0] ,i))
print('----------')
cursor.close()
connect0.close()
if __name__ == "__main__":
main()
...
$ nano ip_socket_inf.py
...
# ip_socket_inf.py
# (c) K.Shimomura (The MIT License)
'''
ipプロトコル、icmpv6タイプ、インターネットファミリ、イーサネットフォーマット 名称変換テーブル
(1) ip v4, ipv6 ヘッダー IPプロトコル
(2) icmpv6 タイプ
(3) socket インターネットファミリ
(4) ethernet フレームフォーマット
'''
# ip v4, ipv6 ヘッダー IPプロトコル
ip_prot_t = ['HOPOPT', 'ICMP', 'IGMP', 'GGP', 'IP-in-IP', 'ST', 'TCP', 'CBT', 'EGP', 'IGP', 'BBN-RCC-MON', 'NVP-II', 'PUP', 'ARGUS', 'EMCON', 'XNET', 'CHAOS', 'UDP', 'MUX', 'DCN-MEAS', 'HMP', 'PRM', 'XNS-IDP', 'TRUNK-1', 'TRUNK-2', 'LEAF-1', 'LEAF-2', 'RDP', 'IRTP', 'ISO-TP4', 'NETBLT', 'MFE-NSP', 'MERIT-INP', 'DCCP', '3PC', 'IDPR', 'XTP', 'DDP', 'IDPR-CMTP', 'TP++', 'IL', 'IPv6', 'SDRP', 'IPv6-Route', 'IPv6-Frag', 'IDRP', 'RSVP', 'GRE', 'DSR', 'BNA', 'ESP', 'AH', 'I-NLSP', 'SwIPe', 'NARP', 'MOBILE', 'TLSP', 'SKIP', 'IPv6-ICMP', 'IPv6-NoNxt', 'IPv6-Opts', 'Any', 'CFTP', 'Any', 'SAT-EXPAK', 'KRYPTOLAN', 'RVD', 'IPPC', 'Any', 'SAT-MON', 'VISA', 'IPCU', 'CPNX', 'CPHB', 'WSN', 'PVP', 'BR-SAT-MON', 'SUN-ND', 'WB-MON', 'WB-EXPAK', 'ISO-IP', 'VMTP', 'SECURE-VMTP', 'VINES', 'IPTM', 'NSFNET-IGP', 'DGP', 'TCF', 'EIGRP', 'OSPF', 'Sprite-RPC', 'LARP', 'MTP', 'AX.25', 'OS', 'MICP', 'SCC-SP', 'ETHERIP', 'ENCAP', 'Any', 'GMTP', 'IFMP', 'PNNI', 'PIM', 'ARIS', 'SCPS', 'QNX', 'A/N', 'IPComp', 'SNP', 'Compaq-Peer', 'IPX-in-IP', 'VRRP', 'PGM', 'Any', 'L2TP', 'DDX', 'IATP', 'STP', 'SRP', 'UTI', 'SMP', 'SM', 'PTP', 'IS-IS', 'FIRE', 'CRTP', 'CRUDP', 'SSCOPMCE', 'IPLT', 'SPS', 'PIPE', 'SCTP', 'FC', 'RSVP-E2E-IGNORE', 'Mobility', 'UDPLite', 'MPLS-in-IP', 'manet', 'HIP', 'Shim6', 'WESP', 'ROHC', 'Ethernet', 'AGGFRAG', 'NSH', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine', 'undefine']
# icmpv6 タイプ
icmpv6_type = {1:"Destination Unreachable",
2:"Packet too Big",
3:"Time Exceeded",
4:"Parameter Problem",
128:"Echo Request",
129:"Echo Reply",
130:"Multicast Listener Query",
131:"Multicast Listener Report",
132:"Multicast Listener Done",
133:"Router Solicitation",
134:"Router Advertisement",
135:"Neighbor Solicitation",
136:"Neighbor Advertisement",
137:"Redirect" }
# socket インターネットファミリ
af_family = {
0:"AF_UNSPEC",
1:"AF_UNIX",
2:"AF_INET",
3:"AF_AX25",
4:"AF_IPX",
5:"AF_APPLETALK",
6:"AF_NETROM",
7:"AF_BRIDGE",
8:"AF_ATMPVC",
9:"AF_X25",
10:"AF_INET6",
11:"AF_ROSE",
12:"AF_DECnet",
13:"AF_NETBEUI",
14:"AF_SECURITY",
15:"AF_KEY",
16:"AF_NETLINK",
17:"AF_PACKET",
18:"AF_ASH",
19:"AF_ECONET",
20:"AF_ATMSVC",
21:"AF_RDS",
22:"AF_SNA",
23:"AF_IRDA",
24:"AF_PPPOX",
25:"AF_WANPIPE",
26:"AF_LLC",
27:"AF_IB",
28:"AF_MPLS",
29:"AF_CAN",
30:"AF_TIPC",
31:"AF_BLUETOOTH",
32:"AF_IUCV",
33:"AF_RXRPC",
34:"AF_ISDN",
35:"AF_PHONET",
36:"AF_IEEE802154",
37:"AF_CAIF",
38:"AF_ALG",
39:"AF_NFC",
40:"AF_VSOCK",
41:"AF_KCM",
42:"AF_QIPCRTR",
43:"AF_SMC",
44:"AF_XDP",
45:"AF_MCTP" }
# ethernet フレームフォーマット
oob_prot_t = {
2048:"Internet IP ( IPv4 )",
2054:"Address Resolution Protocol ( ARP )",
32821:"Reverse Address Resolution Protocol ( RARP )",
32859:"VMTP ( Versatile Message Transaction Protocol )",
32923:"AppleTalk ( EtherTalk )",
33011:"AppleTalk Address Resolution Porotocol ( AARP )",
33079:"IPX ( Novell Netware )",
33100:"SNMP over Ethernet",
33169:"NetBIOS/NetBEUI",
33149:"XTP",
34525:"IP version 6 ( IPv6 )",
34915:"PPPoE Discovery Stage",
34916:"PPPoE Session Stage",
36864:"Loopback ( Configuration Test Protocol )" }
...
2本のソースは同じディレクトリに置く。
これは、データベース作成のときの項目表示用テーブル内容と同じもの。
httpサーバ起動
$ python -m http.server 8080
アクセス可能な別のPCで。
$ curl http://192.168.x.xx
CTRL+C
$ curl http://192.168.x.xx:8080
httpサーバ停止。
プログラムの実行。
$ python dblite.py
..
date : 2025-02-27 09:54:59
oob_prefix : [DROP]
oob_protocol : 2048 / Internet IP ( IPv4 )
ip_protocol : 6 / TCP
tcp_sport : 59836
tcp_dport : 80
oob_in : wlan0
oob_out :
ip_saddr_str : 192.168.x.132
ip_daddr_str : 192.168.x.134
----------
date : 2025-02-27 09:55:07
oob_prefix : [INPUT]
oob_protocol : 2048 / Internet IP ( IPv4 )
ip_protocol : 6 / TCP
tcp_sport : 55094
tcp_dport : 8080
oob_in : wlan0
oob_out :
ip_saddr_str : 192.168.x.132
ip_daddr_str : 192.168.x.134
----------
date : 2025-02-27 10:03:39
oob_prefix : [DROP]
oob_protocol : 2048 / Internet IP ( IPv4 )
ip_protocol : 17 / UDP
udp_sport : 68
udp_dport : 67
oob_in : wlan0
oob_out :
ip_saddr_str : 0.0.0.0
ip_daddr_str : 255.255.255.255
----------
SQL文でログを見る。
$ nano sql-sel1.txt
...
.separator ,
.headers on
select datetime(oob_time_sec + 32400, 'unixepoch') as JST,oob_prefix,af_family,header_prot,icmp_type6, tcp_sport,tcp_dport,udp_sport,udp_dport,oob_in,oob_out,ip_saddr_str,ip_daddr_str from all_in left outer join t_ip_prot on all_in.ip_protocol = t_ip_prot.id left outer join t_af_family on all_in.oob_family = t_af_family.id left outer join t_icmpv6_typ on all_in.icmpv6_type = t_icmpv6_typ.id;
...
SQL文が長いですが。
sudo sqlite3 /var/log/ulog/ulogd_sqlite3.db < sql-sel1.txt
..
JST,oob_prefix,af_family,header_prot,icmp_type6,tcp_sport,tcp_dport,udp_sport,udp_dport,oob_in,oob_out,ip_saddr_str,ip_daddr_str
2025-02-27 09:55:03,[DROP],AF_INET,TCP,,59836,80,,,wlan0,,192.168.x.132,192.168.x.134
2025-02-27 09:55:07,[INPUT],AF_INET,TCP,,55094,8080,,,wlan0,,192.168.x.132,192.168.x.134
2025-02-27 10:03:39,[DROP],AF_INET,UDP,,,,68,67,wlan0,,0.0.0.0,255.255.255.255
...
2025-02-03 「bookworm - podmanインストール」
Raspberry pi 5Bで2024-11-19 bookworm DeskTop イメージを使ってPODMANコンテナを作ってみた。
処理が遅い。Diskスペースに余裕がないとできない。
FROMで指定する種のコンテナ選びが面倒。Raspi-5B用にするにはarm64v8, bookworm用のものを探さなくては行けない。
参考:https://docs.redhat.com/ja/documentation/red_hat_enterprise_linux/8/html/building_running_and_managing_containers/con_configuring-container-registries_working-with-container-registries
3.2. コンテナーレジストリーの設定
$ sudo apt install podman podman-compose
$ podman search debian
何も表示なし
$ podman search docker.io/debian
リスト表示
$ mkdir -p ~/.config/containers
$ nano ~/.config/containers/registries.conf
..
unqualified-search-registries = ["docker.io", "registry.access.redhat.com", "registry.redhat.io"]
short-name-mode = "permissive"
[[registry]]
location="localhost:5000"
insecure=true
..
$ podman search debian
..
NAME DESCRIPTION
docker.io/library/debian Debian is a Linux distribution that's compos...
docker.io/jitesoft/debian Debian base image.
docker.io/dockette/debian My Debian Sid | Jessie | Wheezy Base Images
docker.io/corpusops/debian debian corpusops baseimage
docker.io/treehouses/debian
;;
;;
..
$ podman run docker.io/arm64v8/hello-world
..
;;
;;
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(arm64v8)
;;
...
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
641fcc949ded docker.io/arm64v8/hello-world:latest /hello 2 minutes ago Exited (0) 2 minutes ago nice_wilbur
..
$ podman search raspberrysay
NAME DESCRIPTION
docker.io/tiny69/raspberrysay An Alternative version of cowsay showing a c...
$ podman search --list-tags docker.io/tiny69/raspberrysay
NAME TAG
docker.io/tiny69/raspberrysay fortune
docker.io/tiny69/raspberrysay justsaying
...
フルネームでないと--list-tagsが有効にならない
$ podman run docker.io/tiny69/raspberrysay:justsaying cowsay "Happi--!"
WARNING: image platform ({arm linux [] }) does not match the expected platform ({arm64 linux [] })
__________
< Happi--! >
----------
\
\
\
.~~. .~~.
'. \ ' ' / .'
.~ .~~~..~.
: .~.'~'.~. :
~ ( ) ( ) ~
( : '~'.~.'~' : )
~ .~ ( ) ~. ~
( : '~' : ) Raspberry Pi
'~ .~~~. ~'
'~'
...
$ podman run -it arm64v8/debian /bin/bash
:/# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
...
$ podman ps
実行中のDockerコンテナはない。
$ podman ps -a
ユーザがdockerグループにはいっていないとエラーがでる。
$ podman rm --all
podman ps で表示されたもの以外を全部削除する
$ podman rmi --all
podman images で表示されたものを全部削除する
$ podman run --rm -it arm64v8/debian /bin/bash
--rmをつけて動かす。
どっちにしてもexitすると結果が残せない。ctrl+p, ctrl+q でdocker runを抜け、
$ podman ps
$ podman commit コンテナID イメージID
コンテナID、イメージIDはdocker ps で表示されたもの。
今の環境をイメージに残す時に使う。docker run に戻るには、
$ podman attach コンテナID
自分用の環境を自動で作る。
ロケール日本、タイムゾーンJST, ユーザpi の場合、以下の内容でテキストファイル名"Dockerfile”を作成する。
----Dockerfile-----------
# base/Dockerfile
FROM docker.io/osrf/debian_arm64:bookworm
ENV DEBIAN_FRONTEND=noninteractive
# SIGNAL=37
STOPSIGNAL SIGRTMIN+3
# root パスワード設定
RUN printf "rootdocker\nrootdocker\n"| passwd > /dev/null 2>&1
RUN apt update
# ロケール設定
RUN apt install -y locales locales-all
ENV LC_ALL=ja_JP.UTF-8
ENV LANG=ja_JP.UTF-8
ENV LANGUAGE=ja_JP.UTF-8
ENV TZ=Asia/Tokyo
RUN echo 'export LC_ALL="ja_JP.UTF-8"' >> /etc/profile
RUN echo 'export LANG="ja_JP.UTF-8"' >> /etc/profile
RUN echo 'export LANGUAGE="ja_JP:jp"' >> /etc/profile
RUN echo 'export TZ="Asia/Tokyo"' >> /etc/profile
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# PATH
RUN sed -i -e "s/^.*usr\/games\"$/ PATH=\"\/usr\/local\/sbin:\/usr\/local\/bin:\/usr\/sbin:\/usr\/bin:\/sbin:\/bin:\/usr\/local\/games:\/usr\/games\"/" /etc/profile
# GPIO 設定
RUN groupadd -g 998 i2c
RUN groupadd -g 999 spi
RUN groupadd -g 993 gpio
# ユーザ作成
RUN echo "pi:pidocker:1000:1000:,,,:/home/pi:/bin/bash"|newusers
# ユーザ 設定
RUN cp -r /etc/skel/.[a-z]* /home/pi
RUN chown -R pi:pi /home/pi
RUN adduser pi adm
RUN adduser pi gpio
# 動作環境
RUN apt install -y sudo
RUN printf 'pi ALL=(ALL) NOPASSWD: ALL\n' > /etc/sudoers.d/010_pi-nopasswd
# 開発環境のインストール
RUN apt install -y less nano python3
RUN apt install -y cdebconf net-tools iproute2 tree
RUN apt install -y telnet tcpdump
RUN apt install -y python3-dev python3-pip
RUN apt install -y original-awk install-info
RUN apt install -y patch dpkg-dev build-essential autoconf
RUN apt install -y minisat unzip # libvala-0.48-0
RUN apt install -y ncurses-dev valac valabind libncursesw5-dev
RUN apt install -y sip-dev libzzip-0-13 libzzip-dev zziplib-bin
RUN apt install -y python3-tk python3-setuptools python3-wheel shared-mime-info python3-xdg file python3-keyring
RUN apt install -y git
RUN apt install -y libpython3-dev wget curl
RUN apt install -y python-is-python3
RUN apt install -y iputils-ping nftables
RUN apt install -y apt-utils
COPY raspi.list /etc/apt/sources.list.d
RUN wget http://archive.raspberrypi.org/debian/raspberrypi.gpg.key
RUN apt-key add raspberrypi.gpg.key
RUN apt update
RUN apt install -y ncal python3-gpiozero
RUN apt install -y python3-numpy
COPY chime.py /home/pi
USER pi
WORKDIR /home/pi
CMD ["/bin/bash"]
----作成
$ cp /etc/apt/sources.list.d/raspi.list .
$ nano chime.py
...
from gpiozero import PWMOutputDevice
from time import sleep
buzzer = PWMOutputDevice(pin=19, frequency=440) # 440 Hz is the frequency of the A4 note
try:
print("Playing sound on buzzer...")
while True:
buzzer.value = 0.5 # 50% duty cycle for a continuous tone
sleep(1) # Play the tone for 1 second
buzzer.off() # Turn off the buzzer
sleep(1) # Wait for 1 second before playing again
except KeyboardInterrupt:
print("Program stopped")
finally:
buzzer.close()
...
$ podman build -t base .
タグ名はdocker imagesで表示されるrepository名、Dockefileパスはカレントディレクトリであれば、ドット。
Dockerよりpodmanのほうが作成に時間がかかる
$ podman run --privileged -ti --rm --network host base
networkはホストのnetworkが見えるようになる
$ podman run --privileged --userns=keep-id -ti --rm base python /home/pi/chime.py
--- Buzzer OK --.
chime.pyはコンテナ内にCOPYする。
GPIO-19にピエゾを接続すること。(LED-抵抗でもよい)
$ podman run --privileged --userns=keep-id -ti --rm base pinout
..
WARNING: image platform ({amd64 linux [] }) does not match the expected platform ({arm64 linux [] })
Description : Raspberry Pi 5B rev 1.0
Revision : c04170
SoC : BCM2712
RAM : 4GB
Storage : MicroSD
USB ports : 4 (of which 2 USB3)
Ethernet ports : 1 (1000Mbps max. speed)
Wi-fi : True
Bluetooth : True
Camera ports (CSI) : 2
Display ports (DSI): 2
,--------------------------------.
| oooooooooooooooooooo J8 : +====
| 1ooooooooooooooooooo : |USB2
| Wi Pi Model 5B V1.0 fan +====
| Fi +---+ +---+ |
| |RAM| |RP1| +====
||p +---+ +---+ |USB3
||c ------- +====
||i SoC |c|c J14 |
( ------- J7|s|s 12 +======
| J2 bat uart 1|i|i oo | Net
| pwr\..|hd|...|hd|o|1|0 +======
`-| |-1o|m0|---|m1|--------------'
J8:
3V3 (1) (2) 5V
GPIO2 (3) (4) 5V
GPIO3 (5) (6) GND
GPIO4 (7) (8) GPIO14
GND (9) (10) GPIO15
GPIO17 (11) (12) GPIO18
GPIO27 (13) (14) GND
GPIO22 (15) (16) GPIO23
3V3 (17) (18) GPIO24
GPIO10 (19) (20) GND
GPIO9 (21) (22) GPIO25
GPIO11 (23) (24) GPIO8
GND (25) (26) GPIO7
GPIO0 (27) (28) GPIO1
GPIO5 (29) (30) GND
GPIO6 (31) (32) GPIO12
GPIO13 (33) (34) GND
GPIO19 (35) (36) GPIO16
GPIO26 (37) (38) GPIO20
GND (39) (40) GPIO21
J2:
RUN (1)
GND (2)
J7:
COMPOSITE (1)
GND (2)
J14:
TR01 TAP (1) (2) TR00 TAP
TR03 TAP (3) (4) TR02 TAP
For further information, please refer to https://pinout.xyz/
...
PYTHON計算例
$ nano eig.py
..
import numpy as np
print(np.linalg.eig([[ 6, -3, 5],[-1, 4, -5],[-3, 3, -4]]))
..
$ podman run -v ./eig.py:/home/pi/eig.py -ti --rm base echo "--プログラム";cat eig.py;echo "--答え"; python eig.py
...
WARNING: image platform ({amd64 linux [] }) does not match the expected platform ({arm64 linux [] })
--プログラム
import numpy as np
print(np.linalg.eig([[ 6, -3, 5],[-1, 4, -5],[-3, 3, -4]]))
--答え
(array([3., 2., 1.]), array([[ 7.07106781e-01, -3.01511345e-01, 6.49055182e-16],
[ 7.07106781e-01, -9.04534034e-01, 8.57492926e-01],
[-2.46749603e-15, -3.01511345e-01, 5.14495755e-01]]))
...
2025-01-29 「ラジコ インストール」
参照:
http://mycc.s33.xrea.com/data/rpi/lis_radiko.html
Raspberry Pi用 radiko 簡易聴取スクリプト
http://mycc.s33.xrea.com/data/rpi/lis_radiko.tar.gz
$ env | grep -i runt
XDG_RUNTIME_DIR=/run/user/10xxx
これを覚えておく
lis_radiko.tar.gzを解凍して、修正。
$ nano list_radiko.sh
====
# $ env|grep -i runt で表示される環境変数と内容
export XDG_RUNTIME_DIR=/run/user/10xxx
... 追加
export SDL_AUDIODRIVER=''
export AUDIODEV='' # 出力スピーカー指定を両方''にする
;;
mail='メールアドレス' # ラジコプレミアム
pass='パスワード' # ラジコプレミアム
;;
# 録音する場合はffplayコマンドを以下のように修正
outputfnm="${savedir}/${pname}_$(date +%Y年%m月%d日%H時%M分).mp4"
ffmpeg \
-loglevel error \
-fflags +discardcorrupt \
-headers "X-Radiko-Authtoken: ${authtoken}" \
-i "${suri}${pname}/_definst_/simul-stream.stream/playlist.m3u8" \
-acodec copy \
-vn \
-bsf:a aac_adtstoasc \
-y \
-t 録音時間 \
${outputfnm}
====
使い方:
$ ./lis_radiko.sh LFR
最初の引数に、 ラジコIDを指定。
サウンド出力設定はなしにすると、現在のデスクトップのalasa音量設定での音量となる。
export XDG_RUNTIME_DIRの指定は現在ユーザの環境でalsaの音量となる。ffplay, mplayerに有効。
.bashrc, crontab -eに記述する時に便利。
録音時間は"hh:mm:ss"の形式で指定。hh時間 mm分 ss秒。
上記、参照URLにおすすめのshellタイムフリー録音がある。
2025-02-26 「USB WIFI アダプタで、Wifi AP ルーター」
Raspberry pi 初版ボード,2B の古いボードで2.4GHz、5Ghz AP
▽
|2.4GHz Wlan0 : 192.168.A.99 ==>> 192.168.A.xxx自動割当
| ▽
| |5GHz Wlan1 : 192.168.B.99 ==>> 192.168.B.xxx自動割当
+--------+
| router |
+--------+
|eth0 : 192.168.1.99
(1) Raspberry pi
OS Arm32 bookworm 2024-11-19 lite image , 8MB SD card
(2) 設定
$ sudo raspi-config
...
keyboard
user -- password
host -- ホスト名
ssh
LOCALE ja_JP.UTF-8
timezone Asia/Tokyo
wifi JP
...
(3) sudo reboot
(4) 固定IPアドレス
$ nmcli con show
$ sudo nmcli con mod "有線接続 1" ipv4.addresses 192.168.1.99/24 ipv4.gateway 192.168.1.xx ipv4.dns 192.168.1.xx ipv4.method manual
(5) UGREEN Wi-Fi 無線LAN 子機 AC650 433Mbps + 200Mbps 5GHz/2.4GHz USB ワイヤレス ネットワーク アダプター
子機としては使えるが、WIFI APとしては使えないのでソースからのインストール。
$ sudo apt install -y raspberrypi-kernel-headers build-essential bc dkms git
$ git clone https://github.com/morrownr/8821cu-20210916.git
$ cd 8821cu-20210916
$ sudo ./install-driver.sh
時間がかかる。途中で、
/etc/modprobe.d/8821cu.conf 修正
....
options 8821cu rtw_led_ctrl=1 rtw_country_code=JP
.... +++++++++++
"rtw_country_code=JP"追加
$ sudo reboot
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
◎ELECOM WDC-433SU2M2BK (5GHz)のとき
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
https://github.com/morrownr/8821au-20210708 より
$ sudo apt install -y raspberrypi-kernel-headers build-essential bc dkms git
$ mkdir src
$ cd src
$ git clone https://github.com/morrownr/8821au-20210708.git
$ cd 8821au-20210708
$ sudo ./install-driver.sh NoPrompt
少し時間がかかる
$ make clean
$ make
少し時間がかかる
$ sudo make install
$ sudo reboot
(6) Wifi wlan0 有効
sudo nmcli radio wifi
sudo nmcli radio wifi on
sudo nmcli dev wifi list
SSID一覧表示
(7) Wifi AP 作成
$ nano wp1.sh
---- wp1.sh ----
#!/bin/sh
sudo nmcli con delete raspi-1
sudo nmcli con add type wifi ifname wlan0 mode ap con-name raspi-1 ssid "SSID 1 名前" autoconnect yes
sudo nmcli con modify raspi-1 wifi.band bg
sudo nmcli con modify raspi-1 wifi.channel 7
# 2.4Ghz = wifi.band bg , 5GHz = wifi.band a
sudo nmcli con modify raspi-1 wifi-sec.key-mgmt wpa-psk
sudo nmcli con modify raspi-1 wifi-sec.proto rsn
sudo nmcli con modify raspi-1 wifi-sec.group ccmp
sudo nmcli con modify raspi-1 wifi-sec.pairwise ccmp
sudo nmcli con modify raspi-1 wifi-sec.psk "パスワード 1"
sudo nmcli con modify raspi-1 ipv4.method shared ipv4.address 192.168.x.99/24
sudo nmcli con up raspi-1
----
channel指定して1以外にする。1だと接続しない
sudo nmcli con modify raspi-1 wifi-sec.proto rsn
sudo nmcli con modify raspi-1 wifi-sec.group ccmp
sudo nmcli con modify raspi-1 wifi-sec.pairwise ccmp
Raspberry pi 内蔵2.4GHzWiFiを使うには上の3行はないほうが良い
$ sh wp1.sh
$ nano wp2.sh
---- wp2.sh ----
#!/bin/sh
sudo nmcli con delete raspi-2
sudo nmcli con add type wifi ifname wlan1 mode ap con-name raspi-2 ssid "SSID 2 名前" autoconnect yes
sudo nmcli con modify raspi-2 wifi.band a
sudo nmcli con modify raspi-2 wifi.channel 40
# 2.4Ghz = wifi.band bg , 5GHz = wifi.band a
sudo nmcli con modify raspi-2 wifi-sec.key-mgmt wpa-psk
sudo nmcli con modify raspi-2 wifi-sec.proto rsn
sudo nmcli con modify raspi-2 wifi-sec.group ccmp
sudo nmcli con modify raspi-2 wifi-sec.pairwise ccmp
sudo nmcli con modify raspi-2 wifi-sec.psk "パスワード 2"
sudo nmcli con modify raspi-2 ipv4.method shared ipv4.address 192.168.x.99/24
sudo nmcli con up raspi-2
----
$ sh wp2.sh
接続、raspi-1, 2 --- 情報は以下のディレクトリ
/etc/NetworkManager/system-connections/
nmcli type wifi ifname wlan0 mode ap で指定したcon-nameの
raspi-1.nmconnection、raspi-2.nmconnection ファイルができる
$ sudo nmcli con show "raspi-1"
設定の確認
USBアダプタに2.4GHz,5GHz片方しかない場合は、リブートしたときWLAN0,1が入れ替わる場合はUDEVで固定する
必要がある。
(8) Firewall
$ sudo nano /home/pi/nftables.sh
--- nftables.sh ----
#!/bin/sh
# (c) K.Shimomura (The MIT License)
WLAN_DEV=wlan0 # local lan device
WLAN2_DEV=wlan1
ETH_DEV=eth0 # global lan device
WLAN_ALLOW=192.168.x.0/24 # allow local ip addr (WLAN 0 IPアドレス)
WLAN2_ALLOW=192.168.x.0/24 # (WLAN 1 IPアドレス)
ETH_ALLOW=192.168.x.0/24 # allow eth ip addr (eth0 IPアドレス)
echo "[NFTABLES.SH] **** start ****" > /dev/kmsg
nft flush ruleset
# === ipv6 initial ===
nft add table ip6 filter6
nft add chain ip6 filter6 INPUT { type filter hook input priority 0 \; policy drop \; }
nft add chain ip6 filter6 FORWARD { type filter hook forward priority 0 \; policy drop \; }
nft add chain ip6 filter6 OUTPUT { type filter hook output priority 0 \; policy accept \; }
nft add chain ip6 filter6 POSTROUTING { type nat hook postrouting priority 100 \; policy drop \; }
#nft add rule ip6 filter6 POSTROUTING log prefix \"[NFTABLES6 POST_R]\"
nft add rule ip6 filter6 POSTROUTING drop
#nft add rule ip6 filter6 FORWARD log prefix \"[NFTABLES6 Forward]\"
nft add rule ip6 filter6 FORWARD drop
#nft add rule ip6 filter6 INPUT log prefix \"[NFTABLES6 INPUT]\"
nft add rule ip6 filter6 INPUT drop
# === ipv4 initial ===
nft add table ip filter
nft add chain ip filter INPUT { type filter hook input priority 0 \; policy drop \; }
nft add chain ip filter FORWARD { type filter hook forward priority 0 \; policy drop \; }
nft add chain ip filter OUTPUT { type filter hook output priority 0 \; policy accept \; }
nft add chain ip filter callsub
nft add chain ip filter POSTROUTING { type nat hook postrouting priority 100 \; policy drop \; }
nft add rule ip filter POSTROUTING oifname ${ETH_DEV} masquerade
nft add rule ip filter POSTROUTING oifname ${WLAN_DEV} masquerade
nft add rule ip filter POSTROUTING oifname ${WLAN2_DEV} masquerade
#nft add rule ip filter POSTROUTING log prefix \"[NFTABLES POST_R]\"
nft add rule ip filter FORWARD oifname { ${ETH_DEV} , ${WLAN_DEV}, ${WLAN2_DEV} } ct state related,established accept
nft add rule ip filter FORWARD ip saddr { ${WLAN_ALLOW}, ${WLAN2_ALLOW} } ip daddr { ${WLAN2_ALLOW}, ${WLAN_ALLOW} } accept
nft add rule ip filter FORWARD iifname ${ETH_DEV} ip saddr ${ETH_ALLOW} ip daddr { ${WLAN_ALLOW}, ${WLAN2_ALLOW} } accept
nft add rule ip filter FORWARD ip saddr { ${WLAN_ALLOW}, ${WLAN2_ALLOW} } oifname ${ETH_DEV} accept # for global address
#nft add rule ip filter FORWARD log prefix \"[NFTABLES Forward]\"
nft add rule ip filter INPUT iifname "lo" counter accept
nft add rule ip filter INPUT iifname ${ETH_DEV} ct state related,established accept
nft add rule ip filter INPUT iifname ${WLAN_DEV} ct state related,established accept
nft add rule ip filter INPUT iifname ${WLAN2_DEV} ct state related,established accept
nft add rule ip filter callsub 'tcp flags & (fin|syn|rst|ack) == syn limit rate 5/second burst 5 packets accept'
nft add rule ip filter INPUT ip daddr { ${WLAN_ALLOW}, ${WLAN2_ALLOW}, ${ETH_ALLOW} } meta l4proto {tcp,udp} th dport { 43, 53,123, 443 } accept
nft add rule ip filter INPUT ip daddr { ${WLAN_ALLOW}, ${WLAN2_ALLOW}, ${ETH_ALLOW} } meta l4proto {tcp,udp} th sport 443 jump callsub
nft add rule ip filter INPUT iifname ${ETH_DEV} udp dport 138 jump callsub
nft add rule ip filter INPUT udp dport 5353 accept
nft add rule ip filter INPUT ip daddr { 224.0.0.0/8, 224.0.0.0/8 } accept
nft add rule ip filter INPUT ip daddr {255.255.255.255, ${WLAN_ALLOW}, ${WLAN2_ALLOW} } meta l4proto {tcp,udp} th dport 67-68 accept
nft add rule ip filter INPUT ip daddr { ${ETH_ALLOW}, ${WLAN_ALLOW}, ${WLAN2_ALLOW} } tcp dport 22 jump callsub
#nft add rule ip filter INPUT log prefix \"[NFTABLES INPUT callsub ext]\"
-----
$ chmod +x /home/pi/nftables.sh
192.168.1.xx 192.168.2.xx
▼ wifi-0 ▼ wifi-1
| |
[ ] [ ] wifi-0 , wifi-1 へ接続
| |
+=============+
上記のnftコマンドのmasquerade設定では、wlan0,wlan1は相互接続可能にしているのでルート設定はいらない。
eth0側でのルート設定をされたときの対策はとっていないので注意が必要。
(9) rc.local追加
--- /etc/rc.local ---
#!/bin/sh -e
/home/pi/nftables.sh
exit 0
----
追加する。
$ sudo chmod +x /etc/rc.local
$ sudo systemctl restart rc-local
$ sudo systemctl status rc-local
動作確認
$ sudo reboot
(10) クライアント側での確認
$ sudo nmcli dev wifi list
IN-USE BSSID SSID MODE CHAN RATE SIGNAL BARS SECURITY
* xx:27:xx:CA:33:EE SBxxxxx インフラ 7 65 Mbit/s 75 ▂▄▆_ WPA1 WPA2
参照:
https://github.com/brektrou/rtl8821CU
https://askubuntu.com/questions/1162974/wireless-usb-adapter-0bdac811-realtek-semiconductor-corp
Wireless USB Adapter 0bda:c811 Realtek Semiconductor Corp
◆参考:https://pilink.jp/wifi-ap_pl-r4/
NetWorkManagerだけでラズパイをWi-Fiアクセスポイント化する方法
より、
wifi-sec.pairwise ccmp 、wifi-sec.proto rsn
環認証方式がWPA2、プロトコルがRSN、暗号方式はAES(≒CCMP)設定
2025-01-20 「bookworm - Dockerインストール」
参考1:
https://docs.docker.com/engine/install/debian/
Install Docker Engine on Debian
OS requirements
To install Docker Engine, you need the 64-bit version of one of these Debian versions:
Debian Bookworm 12 (stable)
https://docs.docker.com/engine/install/debian/
https://docs.docker.com/engine/install/raspberry-pi-os/
https://docs.docker.jp/linux/step_one.html
Docker のインストール
参考2:
http://docs.docker.jp/pdf-download.html#id1
Docker ドキュメント日本語版 PDF ダウンロード
SoftwareDesign 2015年12月号 第1特集 Docker自由自在 技術評論社
Dockerエキスパート養成読本 技術評論社
https://raspida.com/rpi4-docker-install/
Raspberry Pi 4でDockerのインストール方法 2023年度版
◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇
RAspberry pi 4BとRaspberry pi 5BとのGPIOのI/Oマップベースアドレスが違うのでDockerインストール後
のコンテナではRaspi-5BではGPIOにアクセスできない。
そのためにコンテナ作成手順を変更した。
◆◆◆◆◆ インストール方法 ◆◆◆◆◆
.... arm64 2024-11-19 Desktop イメージ使用
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh
$ sudo usermod -aG docker `whoami`
$ newgrp docker
$ docker run hello-world
...
;;
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(arm64v8)
;;
...
$ docker ps
実行中のDockerコンテナはない。
ユーザがdockerグループにはいっていないとエラーがでる。
$ docker ps -a
5beaf08a627f hello-world "/hello" About a minute ago Exited (0) About a minute ago jolly_golick
hello-worldのDockerコンテナIDが表示。
$ docker run tiny69/raspberrysay:justsaying cowsay hello
...
;;
_______
Digest: sha256:115eff34a19d0c8aa91a8677cf9431b85eaafe7864d55fc2a0524afd26d5b126
Status: Downloaded newer image for tiny69/raspberrysay:justsaying
_______
< hello >
-------
\
\
\
.~~. .~~.
'. \ ' ' / .'
.~ .~~~..~.
: .~.'~'.~. :
~ ( ) ( ) ~
( : '~'.~.'~' : )
~ .~ ( ) ~. ~
( : '~' : ) Raspberry Pi
'~ .~~~. ~'
'~'
$ docker run -it arm64v8/debian:bookworm /bin/bash
...
# cat /etc/os-release
...
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
# exit
これだとコンテナがいっぱいできる。
$ docker ps
動作中なし
$ docker ps -a
...
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1448e7d4f45 arm64v8/debian "/bin/bash" 9 m......
ea7bd252d167 tiny69/raspberrysay:justsaying "/usr/bin/entry.sh c…" 10 mi....
5beaf08a627f hello-world "/hello" 13 mi....
...
残っている
$ docker rm xxxx表示しているコンテナID
$ docker ps -a
なし。
$ docker run --rm -it arm64v8/debian /bin/bash
--rmをつけて動かす。
どっちにしてもexitすると結果が残せない。ctrl+p, ctrl+q でdocker runを抜け、
$ docker ps
$ docker commit コンテナID イメージID
コンテナID、イメージIDはdocker ps で表示されたもの。
今の環境をイメージに残す時に使う。docker run に戻るには、
$ docker attach コンテナID
コンテナのもとになるdockerイメージ(docker hubにあるもの)を検索するには、
$ docker search キーワード
キーワードはrpi, raspbian, bullseye等で検索して適当なイメージをdocker runで指定する。
自分用の環境を自動で作る。
ロケール日本、タイムゾーンJST, sshサーバ、ユーザpi の場合、以下の内容でテキストファイル名"Dockerfile”を作成する。
----Dockerfile-----------
# base/Dockerfile
FROM arm64v8/debian
ENV DEBIAN_FRONTEND=noninteractive
# SIGNAL=37
STOPSIGNAL SIGRTMIN+3
# root パスワード設定
RUN printf "rootdocker\nrootdocker\n"| passwd > /dev/null 2>&1
RUN apt update
# ロケール設定
RUN apt install -y locales locales-all
ENV LC_ALL=ja_JP.UTF-8
ENV LANG=ja_JP.UTF-8
ENV LANGUAGE=ja_JP.UTF-8
ENV TZ=Asia/Tokyo
RUN echo 'export LC_ALL="ja_JP.UTF-8"' >> /etc/profile
RUN echo 'export LANG="ja_JP.UTF-8"' >> /etc/profile
RUN echo 'export LANGUAGE="ja_JP:jp"' >> /etc/profile
RUN echo 'export TZ="Asia/Tokyo"' >> /etc/profile
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# PATH
RUN sed -i -e "s/^.*usr\/games\"$/ PATH=\"\/usr\/local\/sbin:\/usr\/local\/bin:\/usr\/sbin:\/usr\/bin:\/sbin:\/bin:\/usr\/local\/games:\/usr\/games\"/" /etc/profile
# GPIO 設定
RUN groupadd -g 998 i2c
RUN groupadd -g 999 spi
RUN groupadd -g 993 gpio
# ユーザ作成
RUN echo "pi:pidocker:1000:1000:,,,:/home/pi:/bin/bash"|newusers
# ユーザ 設定
RUN cp -r /etc/skel/.[a-z]* /home/pi
RUN chown -R pi:pi /home/pi
RUN adduser pi adm
RUN adduser pi gpio
# 動作環境
RUN apt install -y init
RUN apt install -y sudo
RUN printf 'pi ALL=(ALL) NOPASSWD: ALL\n' > /etc/sudoers.d/010_pi-nopasswd
RUN apt install -y openssh-server
# 開発環境のインストール
RUN apt install -y less nano python3
RUN apt install -y cdebconf net-tools iproute2 tree
RUN apt install -y bind9-host telnet mailutils tcpdump
RUN apt install -y python3-dev python3-pip
RUN apt install -y original-awk install-info
RUN apt install -y patch dpkg-dev build-essential autoconf
RUN apt install -y minisat unzip # libvala-0.48-0
RUN apt install -y ncurses-dev valac valabind libncursesw5-dev
RUN apt install -y sip-dev libzzip-0-13 libzzip-dev zziplib-bin
RUN apt install -y python3-tk python3-setuptools python3-wheel shared-mime-info python3-xdg file python3-keyring
RUN apt install -y nfs-common
RUN apt install -y libi2c-dev git
RUN apt install -y libpython3-dev wget curl
RUN apt install -y python-is-python3
RUN apt install -y iputils-ping nftables
#RUN apt install -y cron
# install rc.local
RUN printf "#!/bin/sh -e\n\
\n\
echo \"[DOCKER rc.local] **** START ****\"\n\
exit 0\n" > /etc/rc.local
RUN chmod +x /etc/rc.local
RUN apt install -y apt-utils
COPY raspi.list /etc/apt/sources.list.d
COPY sources.list /etc/apt
RUN rm /etc/apt/sources.list.d/debian.sources
RUN wget http://archive.raspberrypi.org/debian/raspberrypi.gpg.key
RUN apt-key add raspberrypi.gpg.key
RUN apt update
RUN apt install -y raspi-utils python3-gpiozero
CMD ["/sbin/init"]
----作成
参照: https://forums.raspberrypi.com/viewtopic.php?t=290058
How do I Get public key for http://archive.raspberrypi.org/debian buster
DeskTop OSでもRASPI 5BでDockerインストールし、そのままでgpiozero,rrpi.gpioをIMPORTしてもエラーとなる。
Raspberry pi5B は、I/Oマップのベースアドレスエラーとなる。install方法を変更した。
raspi-utils と python3-gpiozero のパッケージでコマンドpinout, pinctrlが使用できるようになる。
raspi-5Bでは,rpi.GPIOはI/Oマップベースアドレスエラーとなるので使えない。
raspi-4Bでは,gpiozero と rpi.GPIOは使える。
$ cp /etc/apt/sources.list.d/raspi.list .
$ cp /etc/apt/sources.list .
$ docker build -t base ./Dockerfileパス
タグ名はdocker imagesで表示されるrepository名、Dockefileパスはカレントディレクトリであれば、ドット。
$ docker run --privileged --cap-add SYS_ADMIN -ti --rm -p 222:22 コンテナイメージ名[:タグ名]
login状態になるので、pi -> pidockerでログインできる。
rootはrootdockerでログインできる。
SSHを使う場合は別 IPアドレスから、
$ ssh -p 222 pi@192.168.x.x
パスワードpidockerでログインできる。
LED GPIO-5 PINを点滅
GPIO 5 --[ 510Ω ]--▶‖-----> GND
参照:https://gpiozero.readthedocs.io/en/stable/recipes.html
2. Basic Recipes
上記のDockefileで作成したコンテナをRUNし、pi でログインする。
----
$ docker run --privileged --cap-add SYS_ADMIN -ti --rm -p 222:22 タグ名
user : pi -> password : pidocker
Dockerコンテナ内で、
$ nano led.py
--- led.py ------------
from gpiozero import PWMLED
from signal import pause
led = PWMLED(5)
led.pulse()
pause()
---
$ python led.py
点滅する。
Ctrl+C 終わり
$ sudo poweroff
Dockerコンテナ終了。
==== Docker プライベートレジストリ ====
参考:
https://docs.docker.com/registry/
Docker registry
https://distribution.github.io/distribution/
Docker registry ドキュメント
https://distribution.github.io/distribution/spec/api/
HTTP API V2
https://distribution.github.io/distribution/about/deploying/
Deploy a registry server
(サーバーの使い方)
ドキュメントが詳しくなったからか量が多い。
https://github.com/AlekseyChudov/docker-registry
Python script Docker Registry 一覧:
・・・
プライベートレジストリになる自分のハードディスクに割り当てる。~/Dockerにコンテナイメージが残る。
$ mkdir -p ~/Docker
$ docker run -d -p 5000:5000 -v ${HOME}/Docker:/var/lib/registry -e REGISTRY_STORAGE_DELETE_ENABLED=true --restart always --name registry registry
レジストリイメージ実行
-vはレジストリにアップロードされたイメージを消えないようにローカルマシンの世界へ持ってくるようにする。
-v ${HOME}/Docker:/var/lib/registryの ~/DockerがDcokerホスト側で見えるアップロードされたコンテナが格納されるディレクトリ。
テストは、
$ docker run tiny69/raspberrysay:justsaying cowsay hello
前記で作ったHello コンテナで行う。
$ docker tag tiny69/raspberrysay:justsaying localhost:5000/tiny69/raspberrysay:justsaying
プライベートレジストリの名前をつける。
$ docker push localhost:5000/tiny69/raspberrysay:justsaying
pushするときはタグをつけるようにする。プライベートレジストリへ送る。
Docker Registry コンテナ内のアップロード先ディレクトリの確認は、
$ docker ps
$ docker exec -ti registryコンテナID /bin/sh
/ # cat /etc/docker/registry/config.yml
でストレージ・ファイルシステム・ルートディレクトリを見る。
/ # ls /var/lib/registry/docker/registry/v2/repositories
tiny69がある。
/ # exit
手元にlocalhost:5000/tiny69/raspberrysay:justsayingがないことの確認。
$ docker ps -a
localhost:5000/tiny69/raspberrysay, tiny69/raspberrysay コンテナないこと
$ docker images
$ docker rmi localhost:5000/tiny69/raspberrysay:justsaying
localhost:5000/tiny69/raspberrysay, tiny69/raspberrysay イメージを消す
(REPGITORY, TAG がないものは、IMAGE IDを指定する)
プライベートレジストリからのダウンロード。
$ docker run --rm localhost:5000/tiny69/raspberrysay:justsaying cowsay "Yahho"
________
< Yahho >;
--------
\
\
\
.~~. .~~.
'. \ ' ' / .'
.~ .~~~..~.
: .~.'~'.~. :
~ ( ) ( ) ~
( : '~'.~.'~' : )
~ .~ ( ) ~. ~
( : '~' : ) Raspberry Pi
'~ .~~~. ~'
'~'
●プライベートレポジトリのレポジトリ登録一覧表示
$ curl http://localhost:5000/v2/_catalog
--
{"repositories":["tiny69/raspberrysay"]}
---
$ curl http://localhost:5000/v2/tiny69/raspberrysay/tags/list
--
{"name":"tiny69/raspberrysay","tags":["justsaying"]}
--
で表示できる。v2/よりあとはDocker Resistry API V2 コマンド仕様を参照。
●プライベートレポジトリの登録一覧表示のPythonスクリプトのインストール
$ git clone https://github.com/AlekseyChudov/docker-registry.git
$ cd docker-registry
このままでは動作しないので、以下の修正をする。
$ nano docker-registry
---
#!/usr/bin/env python >>== python2をpythonにする
import urlparse <=この行を以下のように修正
from urllib.parse import urlparse >>== form urllib.parse 追加
class DockerRegistry(object):の最初
def __init__(self, args):
self._args = args
self._registry = urlparse(self._args.url).netloc >>==urlparseのみに修正
self._session = self._create_session()
---
使い方
./docker-registry catalog [name_regex] [tag_regex]
./docker-registry images [name_regex] [tag_regex]
./docker-registry manifest name tag
./docker-registry blob name layer_digest output_file
./docker-registry delete name image_digest
・sudo cp docker-registry /usr/local/sbin
でコピーして使う。
$ ./docker-registry catalog
+----------------+---------------------+------------+
| REGISTRY | NAME | TAG |
+----------------+---------------------+------------+
| localhost:5000 | tiny69/raspberrysay | justsaying |
+----------------+---------------------+------------+
| Total: 1 |
+----------------+---------------------+------------+
$ ./docker-registry -l http://localhost:5000 catalog
+----------------+---------------------+------------+
| REGISTRY | NAME | TAG |
+----------------+---------------------+------------+
| localhost:5000 | tiny69/raspberrysay | justsaying |
+----------------+---------------------+------------+
| Total: 1 |
+----------------+---------------------+------------+
$ ./docker-registry images tiny69/raspberrysay
+----------------+---------------------+------------+------------------------------------------+----------+
| REGISTRY | NAME | TAG | DIGEST | SIZE |
+----------------+---------------------+------------+------------------------------------------+----------+
| localhost:5000 | tiny69/raspberrysay | justsaying | sha256:5020d0a349654c6814720fe9f64506525 | |
| | | | 3ca2b88ad7805355f794ae947b08966 | 63726689 |
+----------------+---------------------+------------+------------------------------------------+----------+
| Total: 1 |
+----------------+---------------------+------------+------------------------------------------+----------+
$ ./docker-registry delete tiny69/raspberrysay sha256:5020d0a349654c6814720fe9f645065253ca2b88ad7805355f794ae947b08966
$ ./docker-registry images tiny69/raspberrysay
+----------------+---------------------+--------+--------+--------+
| REGISTRY | NAME | TAG | DIGEST | SIZE |
+----------------+---------------------+--------+--------+--------+
| localhost:5000 | tiny69/raspberrysay | <none> | <none> | <none> |
+----------------+---------------------+--------+--------+--------+
| Total: 1 |
+----------------+---------------------+--------+--------+--------+
$ ./docker-registry catalog
+----------------+---------------------+--------+
| REGISTRY | NAME | TAG |
+----------------+---------------------+--------+
| localhost:5000 | tiny69/raspberrysay | <none> |
+----------------+---------------------+--------+
| Total: 1 |
+----------------+---------------------+--------+
● プライベートレジストリとは別のクライアントから
docker push するとPUSHしない。
クライアント側のDOCKERサーバに、
sudo nano /etc/docker/daemon.json
---
{ "insecure-registries":["192.168.1.xx:5000"] }
---作成 IPアドレスレポジトリサーバ側のアドレス
sudo systemctl restart docker
で docker push できる。
参考:
https://attonblog.blogspot.com/2018/07/save-my-image-using-docker-registry.html
自前の Docker Registry を立てて、 Build した Image を保存する
・・・
$ docker tag tiny69/raspberrysay:justsaying 192.168.1.xx:5000/tiny69/raspberrysay:justsaying
レポジトリIPアドレス指定
$ docker push 192.168.1.xx:5000/tiny69/raspberrysay:justsaying
DOCKERコンテナイメージ PUSH
$ docker-registry -l http://192.168.1.xx:5000 catalog
PUSH されたイメージがあること
$ docker run --rm 192.168.1.10:5000/tiny69/raspberrysay:justsaying cowsay "wooYahho"
最初はLOGINしてないので実行されない
$ docker login 192.168.1.xx:5000/Docker
ユーザ名とパスワード入力
~/.docker/config.json ファイルができる
あとはLOGINなしでもよい
もう一度RUNすると実行する。
● DOCKER-COMPOSE
参照:https://zenn.dev/sigma_tom/books/e905f2a57b9627/viewer/docker-compose
docker-composeとdocker compose
https://stackoverflow.com/questions/36249744/interactive-shell-using-docker-compose
Interactive shell using Docker Compose
https://stackoverflow.com/questions/45511956/remove-a-named-volume-with-docker-compose
Remove a named volume with docker-compose?
WEB検索でだいたいのコマンドがdocker-composeなので、やってみるとコマンドがないと出る。
$ dpkg -l で
docker-compose-plugin がある。
docker compose コマンドでよい。
①最もシンプルなDockerfileなしのシングルコンテナ
$ nano compose.yaml
...
services:
simple:
container_name: raspisay
image: tiny69/raspberrysay:justsaying
command: cowsay "Yahho--!"
...
$ docker compose up
...
Recreating coeasy ... done
Attaching to raspisay
raspisay | __________
raspisay | < Yahho--! >
raspisay | ----------
raspisay | \
raspisay | \
raspisay | \
raspisay | .~~. .~~.
raspisay | '. \ ' ' / .'
raspisay | .~ .~~~..~.
raspisay | : .~.'~'.~. :
raspisay | ~ ( ) ( ) ~
raspisay | ( : '~'.~.'~' : )
raspisay | ~ .~ ( ) ~. ~
raspisay | ( : '~' : ) Raspberry Pi
raspisay | '~ .~~~. ~'
raspisay | '~'
raspisay |
raspisay exited with code 0
...
この後、docker ps -a でコンテナが残っている。
$ docker compose down
この後、docker ps -a でコンテナが消える。
②shell起動コンテナ
$ nano compose.yaml
...
services:
my-test:
image: arm64v8/debian:bookworm
command: /bin/bash
stdin_open: true
tty: true
...
この定義で以下のコマンド実行で
"docker run -it arm64v8/debian /bin/bash" と同様になる。
$ docker compose run my-test
...
[+] Creating 1/1
レ Network dc1_default Created
0.2s
root@xxa1912a8:/# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
root@xxa1912a8:/# exit
exit
...
$ docker ps -a
コンテナが残る。
$ docker compose run --rm my-test
でコンテナが残らない。
$ docker compose down --remove-orphans
docker ps -a で.yaml関連のコンテナが残っていたらこれで消える。
残るものがある。
********************************************
docker ps -a で表示されたコンテナを全部削除
********************************************
$ nano rm-all
...
#!/bin/sh
for n in `docker ps -a|grep "^[0-9a-zA-Z][0-9a-fA-F]\+"| sed -e "s/[ ]\+/ /g"| cut -d ' ' -f 1`
do
docker stop $n
docker rm $n
done
...
$ chmod +x rm-all
はて?何で実行しないのと言う時, docker ps -aで確認。ポート、リソースが使われているから。
そういう時は, ./rm-all で削除。
=======================================================================================
③DockerfileありのLED点滅シングルコンテナ
LED GPIO-5 PINに配線
GPIO 5 --[ 510Ω ]--(▶led)-----> GND
$ nano compose.yaml
...
services:
led2:
build: .
command: python3 led.py
stdin_open: true
tty: true
privileged: true # GPIO, i2c, SPIアクセスするための定義
...
$ nano Dockerfile
...
# base/Dockerfile
FROM arm64v8/debian:bookworm
RUN apt-get update
RUN apt install -y apt-utils wget dpkg-dev
COPY raspi.list /etc/apt/sources.list.d
RUN wget http://archive.raspberrypi.org/debian/raspberrypi.gpg.key
RUN apt-key add raspberrypi.gpg.key
RUN apt update
RUN apt install -y raspi-utils
RUN apt-get install -y python3 python3-gpiozero
RUN echo "from gpiozero import LED\n\
import time\n\
led = LED(5)\n\
\n\
while(True):\n\
led.on()\n\
time.sleep(1)\n\
led.off()\n\
time.sleep(1)\n\
" > led.py
...
LED点滅プログラムは上記のものと同じ。
$ cp /etc/apt/sources.list.d/raspi.list .
$ docker compose run --rm led2
LEDが点滅する。
プログラムの終了はCTRL+C
④シングルコンテナ複数実行
.
├── .env
├── Dockerfile
├── compose.yaml
├── user1
│ └── ユーザ1
└── user2
└── ユーザ2
$ mkdir user1
$ mkdir user1/ユーザ1
$ mkdir user2
$ mkdir user2/ユーザ2
上記、自分用の環境を自動で作るDockefileでコンテナを作成する。
$ docker build -t base .
$ nano .env
...
USER1=loginx1
ROOT1=dXNlcjE6MDAxCg
USER2=loginx2
ROOT2=VVNFUjI6MDAxCg
HOST=192.168.1.10
U1SSH=2023
U2SSH=2024
...
USER1,USER2,ROOT1,ROOT2は、サービス名1,2のユーザ、ルートのパスワード
HOSTは、DOCKERホストのIPアドレス。 U1SSH,U2SSHは、サービス名1,2に割り当てるポート番号
$ nano compose.yaml
...
networks:
mynet:
ipam:
config:
- subnet: 172.20.3.0/24
services:
os1:
image: base
volumes:
- ./user1:/home/pi/ex
ports:
- ${HOST}:${U1SSH}:22
command: /bin/bash -c "echo -e \"pi:${USER1}\\nroot:${ROOT1}\" | chpasswd && /sbin/init"
privileged: true
restart: always
networks:
mynet:
ipv4_address: 172.20.3.11
os2:
image: base
volumes:
- ./user2:/home/pi/ex
ports:
- ${HOST}:${U2SSH}:22
command: /bin/bash -c "echo -e \"pi:${USER2}\\nroot:${ROOT2}\" | chpasswd && /sbin/init"
privileged: true
restart: always
networks:
mynet:
ipv4_address: 172.20.3.22
...
$ docker compose up -d
2つコンテナが動作。
同じか、違うPCで、
$ ssh -p 2023 pi@192.168.1.10
パスワード loginx1 , ポート2024は、loginx2
raspberry pi LINUXコマンドが使える。
cコンパイラ、pythonはインストールしてあるので使える。
$ tree
. (ここは書き込んでもコンテナ停止で消える)
└── ex (ここ以下の書き込むと残る)
└── ユーザ1 (どっちか判断するための名前)
aptコマンドも使える。
sudo poweroff してもコンテナは停止しない。
$ docker compose down os1
単独コンテナ停止
$ docker compose up -d os1
単独コンテナ起動
$ docker compose down
コンテナ全部停止
コンテナ間通信をしてみる。
コンテナイメージbaseを使って。
$ nano compose.yaml
..
services:
netcap:
image: base
command: ping srv
srv:
image: base
command: sleep infinity
..
$ docker compose up
..
Attaching to netcap-1, srv-1
netcap-1 | PING srv (172.25.0.2) 56(84) bytes of data.
netcap-1 | 64 bytes from dnet-srv-1.dnet_default (172.25.0.2): icmp_seq=1 ttl=64 time=0.201 ms
;;
..
同じコンテナを起動する。
$ nano compose.yaml
..
services:
my-t1:
image: base
privileged: true
ports:
- 192.168.1.10:2025:22
network_mode: bridge
my-t2:
image: base
privileged: true
ports:
- 192.168.1.10:2026:22
network_mode: bridge
my-t3:
image: base
privileged: true
ports:
- 192.168.1.10:2027:22
network_mode: bridge
..
$ docker compose up -d
$ docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
ssh-my-t1-1 base "/sbin/init" my-t1 9 seconds ago Up 8 seconds 192.168.1.10:2025->22/tcp
ssh-my-t2-1 base "/sbin/init" my-t2 9 seconds ago Up 8 seconds 192.168.1.10:2026->22/tcp
ssh-my-t3-1 base "/sbin/init" my-t3 9 seconds ago Up 8 seconds 192.168.1.10:2027->22/tcp
$ docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)
..
/ssh-my-t1-1 - 172.17.0.2
/ssh-my-t3-1 - 172.17.0.4
/ssh-my-t2-1 - 172.17.0.3
..
docker run --privileged --cap-add SYS_ADMIN -ti --rm -p 192.168.1.10:2025:22 base
docker run --privileged --cap-add SYS_ADMIN -ti --rm -p 192.168.1.10:2026:22 base
docker run --privileged --cap-add SYS_ADMIN -ti --rm -p 192.168.1.10:2027:22 base
3コマンドを実行したのと同じになる。
"network_mode: bridge"がないとネットワーク周りが変わる。(Network ssh_default Created が増える)
他のPCより
$ ssh -p 202x pi@192.168.1.10
piユーザ、pidockerでログイン。
$ sudo nft list ruleset
を実行すると違いがわかる。
参照:https://github.com/docker/compose/issues/1259
Docker-compose run command doesnt map ports #1259
++++
$ docker run --privileged --cap-add SYS_ADMIN -ti --rm -p 192.168.1.10:8022:22 コンテナイメージ名[:タグ名]
と同じことをdocker compose run で実行するには、
--- compose.yaml -----
services:
myp:
image: コンテナイメージ名[:タグ名]
privileged: true
ports:
- 192.168.1.10:8022:22
cap_add:
- SYS_ADMIN
---
コマンド:
$ docker compose run -P --rm myp
この時docker psでコンテナイメージがなく、ps -aでコンテナイメージが表示されていると、ポートが割つかない。
$ docker compose run -P --remove-orphans --rm myp
とするとps -a で表示されたコンテナイメージが削除された後にコンテナが実行されるようになり、
ポートが割り当てられる。
++++
参照:https://stackoverflow.com/questions/38088279/communication-between-multiple-docker-compose-projects
Communication between multiple docker-compose projects
https://stackoverflow.com/questions/17157721/how-to-get-a-docker-containers-ip-address-from-the-host
How to get a Docker container's IP address from the host
より、
$ docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)
..
/os-os2-1 - 172.20.3.22
/os-os1-1 - 172.20.3.11
..
IPアドレスを得る。
https://gist.github.com/natcl/3d881d00a56c8a961e6dab8ba51a5a37
docker-compose static IP example
● DOCKERイメージのタグ表示
参考:https://stackoverflow.com/questions/28320134/how-can-i-list-all-tags-for-a-docker-image-on-a-remote-registry
How can I list all tags for a Docker image on a remote registry?
$ nano tags
...
#!/usr/bin/env bash
set -eu -o pipefail
docker_tags() {
item="$1"
case "$item" in
*/*) :;; # namespace/repository syntax, leave as is
*) item="library/$item";; # bare repository name (docker official image); must convert to namespace/repository syntax
esac
authUrl="https://auth.docker.io/token?service=registry.docker.io&scope=repository:$item:pull"
token="$(curl -fsSL "$authUrl" | jq --raw-output '.token')"
tagsUrl="https://registry-1.docker.io/v2/$item/tags/list"
curl -fsSL -H "Accept: application/json" -H "Authorization: Bearer $token" "$tagsUrl" | jq --raw-output '.tags[]'
}
docker_tags "$@"
...
$ chmod +x tags
$ sudo apt install jq
$ ./tags registry
タグ表示
● docker ファイアーウォール
docker ホストはローカルIPでssh接続のみ許可。プライベートレジストリ登録用ポート5000は、localhost のみに開放。
docker コンテナはコンテナ起動時のポート割当で行う。あとはコンテナ内で設定すること。
(1) dockerコンテナのファイアーウォール設定をする。
$ nano nftables.sh
....
#!/bin/sh
afterdkr () {
nft insert rule ip filter DOCKER-USER ip saddr != 127.0.0.0/8 tcp dport 5000 drop
# プライベートレジストリをlocalhostのみ使えるようにする
}
n=0
while [ $n -le 15 ]
do
DKRSRV=`nft list ruleset|grep 'DOCKER-USER'`
if [ "$DKRSRV" != "" ]; then
echo "NFT INSERT1"
afterdkr
exit 0
fi
n=`expr $n + 1`
sleep 1
done
DKRSRV=`nft list ruleset|grep 'DOCKER'`
if [ "$DKRSRV" != "" ]; then
echo "NFT INSERT2"
afterdkr
fi
...
$ chmod +x nftables.sh
(2) dockerサーバーが動作後、docker ホストのファイアーウォールを上書きされたあとに
フィルタDOCKER-USER にコンテナ動作するときの制限を差し込む。
dockerサーバーは、defaultではファイアーウォール上書き設定になっている。
(3) dockerホスト内ファイアウォール
$ nano fw.sh
...
#!/bin/sh
DKR_HOST=192.168.1.xx # ホストアドレス
echo "[NFTABLES.SH] **** start ****" > /dev/kmsg
# === initial ===
nft flush ruleset
# デフォルト
# === ipv4 initial ===
nft add table ip setwall
nft add chain ip setwall input { type filter hook input priority 0 \; policy drop \; }
nft add chain ip setwall callsub
# === ipv4 set input wall ===
nft add rule ip setwall input iifname lo accept
nft add rule ip setwall input ct state { established, related } accept
nft add rule ip setwall input ip protocol icmp accept
nft add rule ip setwall input ct state invalid drop
nft add rule ip setwall input ip daddr ${DKR_HOST} tcp dport 22 jump callsub
nft add rule ip setwall input udp dport { 43, 53,138, 5353,123 } accept
#nft add rule ip setwall input log prefix \"[NFTABLES INPUT] : \"
# --- call sub
nft add rule ip setwall callsub 'tcp flags & (fin|syn|rst|ack) == syn limit rate 5/second burst 5 packets counter accept'
# ... END ...
...
$ chmod +x fw.sh
(4) ファイアーウォール起動
--- /etc/rc.local ---
/xx/xx/fw.sh; /xx/xx/nftables.sh &
exit 0
---- 追加する
$ sudo chmod +x /etc/rc.local
$ sudo systemctl restart rc-local
$ sudo reboot
2024-12-20 「ftpd インストール」
(1) vsftpd
sudo apt install vsftpd
sudo nano /etc/vsftpd.conf
...
listen=NO
listen_ipv6=YES
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
ascii_upload_enable=YES
ascii_download_enable=YES
chroot_local_user=YES
local_root=ftp
secure_chroot_dir=/var/run/vsftpd/empty
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
ssl_enable=NO
allow_writeable_chroot=YES
#pasv_promiscuous=YES
#cmds_denied=EPSV,EPRT
pasv_min_port=3000
pasv_max_port=3010
...
sudo systemctl restart vsftpd
ftp サーバー ユーザルートディレクトリ ~/.ftp
ftpクライアントは、
$ ftp 192.xx.xx.xx
ブラウザではFTP接続できなくなってきている。
ファイル転送でEntering Extended Passive Modeになるのでpassive portの範囲を指定できるので
DOCKERコンテナで使えるようになる。
inetutils-ftpdは指定ができないのでDOCKERコンテナではつかえない。
(2) inetutils-ftpd
sudo apt install ftpd
sudo apt install inetutils-ftpd
sudo nano /etc/ftpchroot
...
pi
ftpserver
...
ユーザ ルートより上に cd できないユーザを設定
sudo nano /etc/inetd.conf
...
ftp stream tcp nowait root /usr/sbin/tcpd /usr/sbin/ftpd
...
inetdで実行する場合
sudo /usr/sbin/ftpd -4 -D
手動実行する場合
sudo apt install ftp
ftp クライアントインストール
2024-12-17 「MIDIシンセサイザ」
サウンドドライバの確認方法
$ pactl info
...
サーバー名: pulseaudio
... pulseaudioのとき
サーバー名: PulseAudio (on PipeWire 1.2.4)
... pipewireのとき
サウンドフォント
/usr/share/sounds/sf2
DeskTop bookworm Arm64 image起動直後にサウンドフォントは入っていた。
/usr/share/sounds
├── sf2
│ ├── TimGM6mb.sf2
│ └── default-GM.sf2 -> /etc/alternatives/default-GM.sf2
└── sf3
└── default-GM.sf3 -> /etc/alternatives/default-GM.sf3
タスクバーに音アイコンがなくなったら、音がでないので、
$ sudo raspi-config
Advanced Option -> Audio Config -> PlusAudio
$ sudo reboot
$ sudo raspi-config (pulsaudioのとき)
Advanced Option -> Audio Config -> PlusAudio以外
$ sudo reboot
Advanced Option -> Audio Config -> PlusAudio
$ sudo reboot
2回リブート
(1)musescore -- MIDI 楽譜で作成ソフト
参照:https://ftp.osuosl.org/pub/musescore/handbook/MuseScore-2.0/MuseScore-ja.pdf
日本語musescoreハンドブック2 PDF
$ sudo apt install musescore
.midファイルを読ませると楽譜が表示される。
▶でプレイすると再生する。特に設定はなし。
音源は、https://musescore.com/sheetmusic
楽譜の画像をクリックしてダウンロードアイコンがウィンドウに表示されたら、
Chromeのウェブストアから、Music Score DownloaderをChromium拡張機能にインストールした
Music Score Downloader拡張機能をクリックして「Download MIDI」で.midファイルをダウンロードする。
それをmusescoreに読み込む。
/usr/share/sounds/
├── sf2
│ ├── TimGM6mb.sf2
│ └── default-GM.sf2 -> /etc/alternatives/default-GM.sf2
├── sf3
│ ├── MuseScore_General.sf3 -> /etc/alternatives/MuseScore_General.sf3
│ ├── MuseScore_General_Lite.sf3
│ └── default-GM.sf3 -> /etc/alternatives/default-GM.sf3
└── sfz
新規作成は、真っ白の楽譜をクリックして楽器を選んで楽譜を作成するか、既成楽譜を選ぶ。
(2)LMMS 音楽作成ソフト
$ sudo apt install lmms
特に設定しなくても楽器音は出た。音が出ないときは、オーディオ設定を変えてみる。
メニュー 編集 -> 設定 -> オーディオ設定 : Pulsaudio - default
マウスでクリック、ドラッグで作れる。
マイサンプル instruments piano01.ogg をソングディタウィンドウにドラッグ。
トラックをダブルクリックでキーボードが表示されるので音階と長さをマウスで入力。
マイサンプルウィンドウで音は聞くことができる。
サウンドファイルにエクスポートすると再生音と同じになる。
MIDIファイルはインポート・エクスポートできるが、エクスポートは楽器情報が付いていかないので他のMIDIソフト再生は注意。
(3)rosegarden : MIDI編集
$ sudo apt install vmpk
$ sudo apt install rosegarden
$ sudo reboot
①rosegarden起動
②vmpk起動
vmpk -- edit -> MODI connection -> in ALSA rosegarden(2) : out SonivoxEAS
ヴァーチャルキーボードに音源を割り当てないと曲が再生されない。
うまく音量が制御できないとか音が出ない場合は設定、リブートを何度かやってみる。
2025-02-19 「USB SSDブート, NVMe SSD, SD card 切り替え」
参考:https://forums.raspberrypi.com/viewtopic.php?p=2198855&hilit=boot+order+gpio#p2198927
Reducing Boot Time?
https://www.raspberrypi.com/documentation/computers/raspberry-pi.html
Raspberry Pi hardware
Raspberry Pi bootloader configuration
スイッチ操作と設定の修正。
配線:
GPIO 21,26 にオンでGNDへ接続するスイッチをつける
GPIO-21 : ---------o/ o----> GND
GPIO-26 : ---------o/ o----> GND
設定:
SDカードBOOT
GPIO-21 : ---------o/ o----> GND
GPIO-26 : ---------o=o----> GND
USB SSD BOOT
GPIO-21 : ---------o=o----> GND
GPIO-26 : ---------o/ o----> GND
NVMe SSD BOOT
GPIO-21 : ---------o/ o----> GND
GPIO-26 : ---------o/ o----> GND
$ sudo rpi-eeprom-config -e
...
[all]
gpio=26=ip,pu
gpio=21=ip,pu
BOOT_UART=1
POWER_OFF_ON_HALT=1
PSU_MAX_CURRENT=5000
[gpio21=0]
BOOT_ORDER=0x4 # USB ssd
[gpio21=1]
BOOT_ORDER=0x6 # NVMe ssd
[gpio26=0]
BOOT_ORDER=0x1 # sd card
...
(注)GPIO-26がオンの場合はGPIO-26オンが優先
$ sudo reboot
$ vcgencmd bootloader_config
確認
2024-12-03 「Apache + FLASK + Flask.BASIC.Auth」
Apache2、Flask , Flask・BASIC認証を使ってWEBアプリを作る。
ファイルアップロード追加。
・ディレクトリ構成
/home/flask/
└─f_app
├── application # FLASK static directory
│ ├── program # application program directory
│ │ └── app1.py # application program
│ └── upload # files upload directory
├── flask1.wsgi # FLASK wsgi file
├── fmain.py # FLASK Main program
├── form # FLASK form directory
│ ├── default.html # demo html
│ └── index.html # opening html
├── getlog.sh # get error log script
├── test.sh # check user mode script
└── test99.txt # check UID=flask,GID=www-data
UID,GIDがkbdb1.confで定義したユーザ、グループIDを確認すること
Raspberry Pi OS LiteはFLSKが入っていないので、
$ sudo apt install python3-flask
でインストールすること。
主な追加部分。
・・・・
html: <input type="file" name="sendfile" multiple="true" autocomplete="off" accept=".txt,.pdf">
fmain.py:
POST後に、HTTP引数取り出し。
POST引数リスト = request.form.to_dict(flat=False)
POSTマルチファイルデータリスト = request.files.getlist('sendfile')
ダウンロード。
for file in POSTマルチファイルデータリスト:
if file.filename == '':
continue
filename = file.filename
file.save(os.path.join('/tmp', filename))
filePath = mydir + '/' + file.filename
newPath = cnv_name(filePath[:800]) # 長さ制限、HTML文字、'#'文字変換
if not os.path.isdir(mydir):
os.makedirs(mydir) # Uploadディレクトリ作成
shutil.move('/tmp/' + filename, newPath) # 新しい名前で移動
・・・・
・作成手順
----------- setup.sh -------------
#!/bin/bash
if [ "$1" != "" ]; then
echo $1 > set.ini
else
echo "0" > set.ini
fi
stp=`cat set.ini`
nxt=`expr $stp + 1`
echo $nxt > set.ini
case $stp in
10)
# ==========================================
# == FLASK ユーザ登録
# ==========================================
echo "=== ユーザ設定 ==="
echo "... flask ..."
echo "flask:nov04flask:::,,,:/home/flask:/bin/bash"|sudo newusers
# /home/flask の パーミッションビットが、rwxr-xr-xになる
# $ sudo adduser flask コマンドでは、パーミッションビットが、rwx------になる
# adduserのあとでは、
# $ sudo chmod +x /home/flask コマンドを実行すること
#
sudo adduser flask adm
;;
20)
# ==========================================
# == APCHE2 INSTALL
# ==========================================
echo "apache2 install"
sudo apt install -y apache2
sudo apt install -y zip
echo "-apache2 settings"
sudo sed -i".org" -e "s/ServerTokens OS/ServerTokens Prod/" -e "s/#ServerSignature Off/ServerSignature Off/" -e "s/ServerSignature On/#ServerSignature On/" /etc/apache2/conf-enabled/security.conf
sudo systemctl enable apache2
sudo systemctl restart apache2
sudo systemctl status apache2
echo "-----APACHE TEST ---"
echo "ブラウザで確認。"
echo " http://localhost"
echo "--------------------"
echo ""
;;
30)
# ==========================================
# === INSTALL FLASK
# ==========================================
sudo adduser www-data adm
# ^^^^^ ^^^ for apache2 error.log
sudo a2dissite 000-default
# ^^^^^^^^^^^ Only flask1.conf
sudo apt install -y libapache2-mod-wsgi-py3
sudo apt install -y python3-flask-httpauth
NOTE_DIR="/home/flask"
NOTE_NAME="flask"
# ###### Flask directory #######
sudo mkdir -p ${NOTE_DIR}/f_app/
sudo mkdir -p ${NOTE_DIR}/f_app/form
sudo mkdir -p ${NOTE_DIR}/f_app/application
sudo mkdir -p ${NOTE_DIR}/f_app/application/program
# -------------------------------------
#/home/flask/
# └── f_app
# ├── application # FLASK static directory
# │ ├── program # application program directory
# │ │ └── app1.py # application program
# │ └── upload # files upload directory
# ├── flask1.wsgi # FLASK wsgi file
# ├── fmain.py # FLASK Main program
# ├── form # FLASK form directory
# │ ├── default.html # demo html
# │ └── index.html # opening html
# ├── getlog.sh # get error log script
# ├── test.sh # check user mode script
# └── test99.txt # check UID=flask,GID=www-data
# # ^^^ http://localhost/who
#
# ##########################################
# ## flask1.conf
# ##########################################
cat <<EOF | sudo tee /etc/apache2/sites-enabled/flask1.conf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot ${NOTE_DIR}/f_app
WSGIDaemonProcess flask1 user=flask group=www-data threads=5 locale=ja_JP.UTF-8
WSGIScriptAlias / ${NOTE_DIR}/f_app/flask1.wsgi
WSGIPassAuthorization On
<Directory ${NOTE_DIR}/f_app>
WSGIProcessGroup flask1
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog \${APACHE_LOG_DIR}/error.log
CustomLog \${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
EOF
# ##########################################
# ## flask1.wsgi
# ##########################################
sudo cp flask1.wsgi ${NOTE_DIR}/f_app
# ##########################################
# ###### fmain.py #######
# ##########################################
sudo cp fmain.py ${NOTE_DIR}/f_app/fmain.py
sudo cp app1.py ${NOTE_DIR}/f_app/application/program
# ##########################################
# ###### form/index.html #######
# ##########################################
sudo cp index.html ${NOTE_DIR}/f_app/form
# ##########################################
# ###### ./test.sh #######
# ##########################################
sudo cp default.html ${NOTE_DIR}/f_app/form
# ##########################################
# ###### ./test.sh #######
# ##########################################
sudo cp test.sh ${NOTE_DIR}/f_app
# ##########################################
# ###### getlog.sh #######
# ##########################################
sudo cp getlog.sh ${NOTE_DIR}/f_app
sudo chown -R ${NOTE_NAME}:${NOTE_NAME} ${NOTE_DIR}/f_app
sudo adduser flask www-data
sudo systemctl restart apache2
;;
100)
# ==========================================
# === List FLASK
# ==========================================
NOTE_DIR="/home/flask"
echo "%%%%%%%%%%%%%%% flask1.wsgi %%%%%%%%%%%%%%%%%%"
cat ${NOTE_DIR}/f_app/flask1.wsgi
echo ""
echo "%%%%%%%%%%%%%%% fmain.py %%%%%%%%%%%%%%%%%%"
cat ${NOTE_DIR}/f_app/fmain.py
echo ""
echo "%%%%%%%%%%%%%%% app1.py %%%%%%%%%%%%%%%%%%"
cat ${NOTE_DIR}/f_app/application/program/app1.py
echo ""
echo "%%%%%%%%%%%%%%% index.html %%%%%%%%%%%%%%%%%%"
cat ${NOTE_DIR}/f_app/form/index.html
echo ""
echo "%%%%%%%%%%%%%%% default.html %%%%%%%%%%%%%%%%%%"
cat ${NOTE_DIR}/f_app/form/default.html
echo ""
echo "%%%%%%%%%%%%%%% test.sh %%%%%%%%%%%%%%%%%%"
cat ${NOTE_DIR}/f_app/test.sh
echo ""
echo "%%%%%%%%%%%%%%% getlog.sh %%%%%%%%%%%%%%%%%%"
cat ${NOTE_DIR}/f_app/getlog.sh
echo ""
;;
*)
echo "none"
;;
esac
exit 0
ーーー ファイル一式 ーーーーー
%%%%%%%%%%%%%%% flask1.wsgi %%%%%%%%%%%%%%%%%%
#!/usr/bin/python
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/home/flask/f_app/")
from fmain import app as application
%%%%%%%%%%%%%%% fmain.py %%%%%%%%%%%%%%%%%%
#! /bin/usr/python
from flask import Flask,request,flash
from flask import render_template
from flask_httpauth import HTTPBasicAuth
from werkzeug.security import generate_password_hash, check_password_hash
import os
from subprocess import check_output
import subprocess
import application.program.app1 as appx
app = Flask(__name__, static_folder='application', template_folder='form')
auth = HTTPBasicAuth()
users = { "gozira": generate_password_hash("kingkong"),
"tiger": generate_password_hash("doragon") }
do_dir = os.path.dirname(__file__)
@auth.verify_password
def verify_password(username, password):
if username in users and \
check_password_hash(users.get(username), password):
return username
@app.route("/<string:path>")
@app.route("/<path:path>")
@app.route("/application/program/<path:path>")
@app.route('/')
def hello(path=None):
return render_template('index.html',acomment=path)
@app.route('/open')
@auth.login_required
def homepage():
bf = ['']
appx.ddir(bf, do_dir + '/application/upload')
return render_template('default.html',flist=bf[0])
@app.route('/who')
def whoami():
cmd = do_dir + "/test.sh"
result = subprocess.run(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True)
return(result.stdout.decode('utf-8'))
@app.route("/get-req")
def get_request():
prm = request.args.to_dict()
retrn = "<html><body><pre>" + str(request.url) + chr(0x0a) + str(request.host_url) + chr(0x0a) + "</pre>"
for k in prm:
data = prm.get(k)
if data != None:
retrn += "P["+k+"]=" + str(data) + "<br>"
retrn += "<br>config<br>"
for k in app.config:
retrn += k + "=" + str(app.config.get(k)) + "<br>"
retrn += "<hr>"
for x in os.environ:
retrn += x + "= " + os.getenv(x) + "<br>"
retrn += "<hr>"
for x in app.config:
retrn += str(x) + "= " + str(app.config[x]) + "<br>"
retrn += "</body></html>"
return retrn
@app.errorhandler(500)
@app.errorhandler(400)
@app.errorhandler(401)
@app.errorhandler(403)
@app.errorhandler(404)
def not_found(e):
import re
rhtml = """<!doctype html><html><html lang="ja"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">"""
rhtml += "<title>"
rhtml += str(e.code)
rhtml += """</title><body><h1 style="color:red">"""
rhtml += str(e.code)
rhtml += """エラーが発生しました??</h1><br><h3 style="color:bule">"""
rhtml += e.name
rhtml += "</h3>"
rhtml += request.url
rhtml += "<hr>"
prm = request.args.to_dict()
for k in prm:
rhtml += "[" + k + "]:" + prm.get(k) + "<br>"
if e.code == 500:
rhtml += "<hr>"
cmd = do_dir + "/getlog.sh"
elog = check_output(cmd,stderr=subprocess.STDOUT,shell=True)
rhtml += elog.decode('utf-8',errors='replace').replace('\n','<br>')
rhtml += "<br></body></html>"
return rhtml,e.code
@app.route('/e40x')
def e40x():
rhtml = """<!doctype html><html><html lang="ja"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">"""
rhtml += "<title>Not Access</title><body><h1 style=\"color:red\">アクセスできません。</h1></body></html>"
return rhtml
@app.route('/function/<name>',methods=['GET', 'POST'])
@auth.login_required
def call_subr(name):
subcall = {'あいさつ':appx.aisatu,'あさ':appx.asa,'ゆうがた':appx.yuugata,
'たのしい':appx.tanosi, 'これで':appx.korede,'おわり':appx.owari }
if request.method == 'POST':
prm = request.form.to_dict(flat=False)
files = request.files.getlist('sendfile')
else:
prm = request.args.to_dict(flat=False)
if name in subcall:
if name == 'たのしい':
return appx.tanosi(prm,files,do_dir + '/application/upload')
return subcall[name](prm)
else:
return "関数:"+name+"なし"
@app.route('/logout')
def logout():
auth = request.authorization
if auth == None:
return "ログアウト"
else:
return "LogOut, {}!".format(auth.username), 401
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5050)
%%%%%%%%%%%%%%% app1.py %%%%%%%%%%%%%%%%%%
#! /bin/usr/python
from werkzeug.utils import secure_filename
import os
import shutil
def cnv_name(s):
nsf = s.replace('&','[ap]')
nsf = nsf.replace('<','[lt]')
nsf = nsf.replace('>','[gt]')
nsf = nsf.replace('"','[qu]')
nsf = nsf.replace('%22','[=]')
nsf = nsf.replace('+','[2B]')
nsf = nsf.replace('#','[23]')
nsf = nsf.replace('`','[vq]')
nsf = nsf.replace("'",'[sq]')
nsf = nsf.replace('~','[ch]')
return nsf
def Aprint(buf, strtxt):
buf[0] += strtxt
def ddir(bf, mydir):
if not os.path.isdir(mydir):
os.makedirs(mydir)
Aprint(bf, '<br>========<br>ファイル一覧<br>========<br>')
for f in os.listdir(mydir):
if os.path.isfile(os.path.join(mydir, f)):
fsiz = os.path.getsize(os.path.join(mydir, f))
if fsiz >= 1024:
ss = "(%.1f KB)" % ((fsiz+103)/1024)
else:
ss = "(%d B)" % (fsiz)
Aprint(bf, '<a href="/application/upload/' + f + '" target="_blanck" >['+f+ss+']</a><br>')
def btn():
return "<br><br><button style=\"background-color: cyan;\" type=\"button\" onclick=\"location.href='/open'\">戻 る</button><br><br><button style=\"background-color: yellow;\" type=\"button\" onclick=\"location.href='/logout'\">ログアウト</button>"
def aisatu(p):
return "はじめまして" + btn()
def asa(p):
return "おはよう" + btn()
def yuugata(p):
return "こんばんは" + btn()
def tanosi(p, files, mydir):
for file in files:
if file.filename == '':
continue
filename = file.filename
file.save(os.path.join('/tmp', filename))
filePath = mydir + '/' + file.filename
newPath = cnv_name(filePath[:800])
if not os.path.isdir(mydir):
os.makedirs(mydir)
shutil.move('/tmp/' + filename, newPath)
retrn = '<pre>'
for k in p:
data = p.get(k)
if data != None:
retrn += "P["+k+"]:\n" + data[0] + "\n"
bf = ['']
ddir(bf, mydir)
return retrn + bf[0] + "\nいいね !</pre>" + btn()
def korede(p):
return "こんなんじゃ、もうおわりだ" + btn()
def owari(p):
return "さようなら" + btn()
%%%%%%%%%%%%%%% index.html %%%%%%%%%%%%%%%%%%
<html>
<head>
<style type='text/css'>
<!--
body {
margin:0px;
padding:10px;
text-align:center;
}
hr { width: 500px; }
-->
</style>
</head>
<body>
<h1>Welcome to My FLASK Server.</h1>
<form action="/open" method="get">
<p>BASIC認証を使ってみる</p>
<p>User: tiger, gozira</p>
<a href="/open"><input type="button" value="認 証"></a>
<p>
{% if acomment %}
<br>こちらは見れません:{{ acomment | safe }}<br>
{% endif %}
</p>
<hr>
<a href='/logout'><input style="background-color: yellow;" type="button" value="ログアウト"></a>
</body>
</html>
%%%%%%%%%%%%%%% default.html %%%%%%%%%%%%%%%%%%
<!doctype html>
<html lang=ja>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<style type='text/css'>
<!--
body {
margin: 0px;
padding:0px;
text-align:center;
}
.menu00 { text-align: right; margin: 5px; padding: 50px 5px 5px;}
.body00 { width: 70%; }
.main{ width: 800px; display: flex;}
h1, h3 { margin: auto;padding: 10px}
h1 { color: orange; }
h3 { color: blue; }
menu { list-style-type: none;}
li { witdh: 40px; margin: 10px;}
.menuX { background-color: cyan; }
.menuE { background-color: yellow; }
label { margin: 0; padding: 0;}
-->
</style>
<title>メイン</title>
</head>
<body style="width: 800px; margin: auto;">
<div class='main'>
<div class='menu00'>
メニュー 
<menu>
<li><button class="menuX" type="button" onclick="location.href='/function/あいさつ'">挨 拶</button></li>
<li><button class="menuX" type="button" onclick="location.href='/function/あさ'">朝 で す</button></li>
<li><button class="menuX" type="button" onclick="location.href='/function/ゆうがた'">夕 方</button></li>
<li><button class="menuX" type="button" onclick="location.href='/function/これで'">どうした </button></li>
<li><button class="menuX" type="button" onclick="location.href='/function/おわり'">や め た</button></li>
<li><button class="menuE" type="button" onclick="location.href='/logout'">ログアウト</button></li>
</menu>
</div>
<div class='body00'>
<h1>FLASK Server.</h1>
<h3>コメント</h3>
<div style="display: inline-table;">
<form method="post" action="/function/たのしい" enctype="multipart/form-data">
<div style="display: inline-table;">
<textarea name="comment" cols="90%" rows="8"></textarea>
<div style="display: flex; justify-content: center; align-items: center;">
評価: <label><input type="radio" name="iiwaru" value="yoi">良かった</label>
<label><input type="radio" name="iiwaru" value="futuu">普通</label>
<label><input type="radio" name="iiwaru" value="warui">悪い</label>
</div>
<p>添付ファイル(*.txt,*.pdf) <input type="file" name="sendfile" multiple="true" autocomplete="off" accept=".txt,.pdf"> コメント<input type="submit" value="送信"></p>
</div>
</form>
</div>
{% if flist %}
{{ flist | safe }}
{% endif %}
<div>
</div>
</body>
</html>
%%%%%%%%%%%%%%% test.sh %%%%%%%%%%%%%%%%%%
#!/bin/sh
echo "<!DOCTYPE html>"
echo "<html lang=ja>"
echo "<head>"
echo "<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>"
echo "<title>わお!</title>"
echo "</head>"
echo "<body>"
DATA=`whoami`
echo "<H1>user : $DATA</h1>"
WDIR=$(dirname -- "$0")
echo $DATA > ${WDIR}/test99.txt
echo "</body>"
echo "</html>"
%%%%%%%%%%%%%%% getlog.sh %%%%%%%%%%%%%%%%%%
#!/bin/sh
tail -n 10 /var/log/apache2/error.log
exit 0
2024-10-03 「行列式計算2」
順列と入れ替え回数計算を使って、行列式計算を公式どうりにやってみた。
行列が大きくなると遅いです。
参照:
数学ターミナル 新訂2版 線型代数の発想 小林幸夫 著 現代数学社 2008,2020,2023
1.6.2 行列式関数の性質 行列式関数detの定義
その他、行列式に関する本より。
初等線形代数 --考え方と応用プログラム 石原辰雄・長谷川勝也 著 共立出版 1986,1988
DET.DET
[改定新版]C言語による標準アルゴリズム事典 奥村晴彦著 技術評論社 1991,2018
順列 nextperm()
https://ikatakos.com/pot/programming_algorithm/dynamic_programming/inversion
転倒数
========
実行:
実行結果: 答 = det_det() - 行列式計算
参照:数学ターミナル 新訂2版 線型代数の発想 小林幸夫 著 現代数学社 2008,2020,2023
1.6.2 行列式関数の性質 行列式関数detの定義
参照:初等線形代数 --考え方と応用プログラム 石原辰雄・長谷川勝也 著 共立出版 1986,1988
DET.DET
参照:[改定新版]C言語による標準アルゴリズム事典 奥村晴彦著 技術評論社 1991,2018
順列 nextperm()
その他、行列式に関する本より。
参照:https://ikatakos.com/pot/programming_algorithm/dynamic_programming/inversion
転倒数
....
--- 行列計算 --- test-1
## 入力: ##
[[ 5 ]]
ランク(A): 1 , 1 x 1 行列
My det(): 5.0000
Numpy det(): OK
--- 行列計算 --- test-2
## 入力: ##
[[ 4 3 ]
[ 1 3 ]]
ランク(A): 2 , 2 x 2 行列
My det(): 9.0000
Numpy det(): OK
--- 行列計算 --- test-3
## 入力: ##
[[ 0 -2 0 ]
[ -1 5 2 ]
[ 0 -1 1 ]]
ランク(A): 3 , 3 x 3 行列
My det(): -2.0000
Numpy det(): OK
--- 行列計算 --- test-4
## 入力: ##
[[ 1 -1 -1 ]
[ -1 1 -1 ]
[ -1 -1 1 ]]
ランク(A): 3 , 3 x 3 行列
My det(): -4.0000
Numpy det(): OK
--- 行列計算 --- test-5
## 入力: ##
[[ 7 2 -4 2 3 ]
[ 1 5 2 0 3 ]
[ -5 -6 3 1 2 ]
[ 0 2 7 4 3 ]
[ 4 2 -5 -3 5 ]]
ランク(A): 5 , 5 x 5 行列
My det(): -2346.0000
Numpy det(): OK
--- 行列計算 --- test-6
## 入力: ##
[[ 1 3 9 ]
[ -1 1 -1 ]
[ 2 -4 -2 ]]
ランク(A): 2 , 3 x 3 行列
My det(): 0.0000
Numpy det(): OK
--- 行列計算 --- test-7
## 入力: ##
[[ 1 9 2 12 ]
[ 3 2 5 10 ]
[ 2 -1 6 7 ]
[ 0 6 1 7 ]]
ランク(A): 3 , 4 x 4 行列
My det(): 0.0000
Numpy det(): OK
--- 行列計算 --- 生成行列 - 1 : 9 x 9
## 入力: ##
[[ 2.2 -1 3.3 -4 -5 -0.5 3.8 -4.2 -4.7 ]
[ 0.8 -4 0.7 -3.6 2.1 -4.9 -0.5 1.6 1.8 ]
[ -0.5 3.2 4.8 2.8 0.7 -3.2 -4.9 2.9 -0.2 ]
[ 4.1 4.9 -2.5 4.1 -4.9 -0.4 2.8 -2.4 5 ]
[ 3.6 -0.7 4.5 -2.1 2.9 -1.8 -0.1 3.2 4.4 ]
[ 2.4 -3.2 -4.8 4 -1.6 -2.9 2.3 1.3 -0.5 ]
[ -2.4 -1 -4.5 2.2 5 1.2 -5 -2.4 3.4 ]
[ 0.7 -2.6 3.2 -3.5 0.4 2.1 0.4 -2 3.6 ]
[ 0.1 -1.8 2.7 0.1 -4.6 -3.3 0.6 -4 1.5 ]]
ランク(A): 9 , 9 x 9 行列
My det(): 5497274.1853
Numpy det(): OK
--- 行列計算 --- 生成行列 - 2 : 8 x 8
## 入力: ##
[[ -0.6 -1.1 5 4.4 -1.7 2.4 4 2.3 ]
[ 2 2.5 3.9 1.9 3.2 -4.8 -3.9 -3.9 ]
[ 1.4 2.6 -0.9 -4.2 1.6 -0.3 4.2 1.9 ]
[ 3.5 -2.6 -3.2 0.1 -1.3 0 1.2 3.6 ]
[ 1.4 -4.3 -3.5 -0.8 -2.2 0.6 3.1 -4.7 ]
[ -2.6 4.6 0.2 5 -2.9 3.5 1.6 3.7 ]
[ 1.5 -1.9 -2.8 0.8 -3.6 1.3 -3 -1.2 ]
[ -2.3 -3.7 -2.5 4.6 3.9 -0.2 0.7 3.3 ]]
ランク(A): 8 , 8 x 8 行列
My det(): 655590.1626
Numpy det(): OK
--- 行列計算 --- 生成行列 - 3 : 8 x 8
## 入力: ##
[[ 5 3.9 5 0.4 -2.4 4.3 -2.1 0.7 ]
[ -4.3 -3.4 4.6 0.4 -0.4 -1.5 0 -1.3 ]
[ -0.9 -3.5 1.9 0.1 -0.6 -0.2 -4.9 0 ]
[ -3.3 -4.7 4.8 -1.1 2 1.9 -1.9 -4.3 ]
[ 3.2 -2.8 -1.3 2.9 1.4 -2.4 2.4 5 ]
[ 1.8 3.9 -4.4 -3.8 2.1 -2.6 -3 -0.4 ]
[ -4.8 3.1 0.9 -0.1 -0.5 0.1 -3.3 1.2 ]
[ -5 2.4 -3 2.4 3.5 -4.8 -0.5 3.7 ]]
ランク(A): 8 , 8 x 8 行列
My det(): 619456.4268
Numpy det(): OK
.......................
プログラム:
-------------- matrix2.py ------------------
"""
https://ikatakos.com/pot/programming_algorithm/dynamic_programming/inversion
転倒数
"""
def get_sgn(Z):
cnt = 0
n = len(Z)
for i in range(1,n):
for j in range(i+1,n):
if Z[i] > Z[j]:
cnt += 1
return (-1)**(cnt&1)
"""
[改定新版]C言語による標準アルゴリズム事典 奥村晴彦著 技術評論社 1991,2018
順列 nextperm()
"""
def nextperm(mP):
"""
順列生成
"""
N = len(mP) - 1
i = N - 1
mP[0] = 0
while mP[i] >= mP[i+1]:
i -= 1
if i == 0:
return 0
j = N
while mP[i] >= mP[j]:
j -= 1
t = mP[i]
mP[i] = mP[j]
mP[j] = t
i += 1
j = N
while i < j:
t = mP[i]
mP[i] = mP[j]
mP[j] = t
i += 1
j -= 1
return 1
"""
数学ターミナル 新訂2版 線型代数の発想 小林幸夫 著 現代数学社 2008,2020,2023
1.6.2 行列式関数の性質 行列式関数detの定義
初等線形代数 --考え方と応用プログラム
石原辰雄・長谷川勝也 著 共立出版 1986,1988
DET.DET
その他、行列式に関する本より。
"""
def det_det(A):
"""
行列式計算
"""
# x = N!
# +-- +--
# \ \
# \ / A[1][Q[1]] * A[2][Q[2] * ... * A[n][Q[n]] * sgn(Q)
# Det = / +--
# / Q = Z[x]
# +--
# N次順列 --> Z[N!] = [[1, 2, 3],[1, 3, 2],[2, 1, 3],[2, 3, 1],[3, 1, 2], [3, 2, 1]]
# x = 0 例えば3の場合、p[6][3]の配列となる
#
n = len(A)
Q = [ _ for _ in range(n+1)] # 順列初期値
det = 0
while True:
d = 1
for j in range(n):
d *= A[j][Q[j+1]-1]
d *= get_sgn(Q)
det += d
if nextperm(Q) == 0:
break
return det
def gen_matrix(n=0, RMAX=50, DCP=-1):
'''
行列生成 N x N
n = 0 : ランダムNxN , 9 : 9 x 9行列
RMAX = 50 : (+-50)で要素データ、 99: (+-99)で要素データ
DCP = 1 : 要素データ * 10, +9 : 要素データ * (10**9) 、 -9 : 要素データ / (10**9)
'''
import random as r
DC = 10**abs(DCP)
if n == 0:
N = r.randrange(4,10) # 4x4 ~ 9x9の行列を作る
else:
N = n # n x n の行列を作る
m = []
for i in range(N):
m.append([r.randrange(-RMAX,RMAX+1) for j in range(N)])
for i in range(N):
for j in range(N):
if DCP < 0:
m[i][j] /= DC
else:
m[i][j] *= DC
return m
def pmatrix(msg, MAT):
'''
行列の印刷
'''
print("##",msg,"##")
if MAT is None:
print(" 結果がありません")
return
n = len(MAT)
m = len(MAT[0])
for i in range(n):
if i == 0:
print("[[",end='')
else:
print(" [",end='')
for j in range(m):
print(" % 5.4g" % (MAT[i][j]), end='')
if i == (n-1):
print(" ]]")
else:
print(" ]")
# ##################################
if __name__ == '__main__':
import numpy as np
def p_header():
print("実行結果: 答 = det_det() - 行列式計算")
print(" 参照:数学ターミナル 新訂2版 線型代数の発想 小林幸夫 著 現代数学社 2008,2020,2023")
print(" 1.6.2 行列式関数の性質 行列式関数detの定義")
print(" 参照:初等線形代数 --考え方と応用プログラム 石原辰雄・長谷川勝也 著 共立出版 1986,1988")
print(" DET.DET")
print(" 参照:[改定新版]C言語による標準アルゴリズム事典 奥村晴彦著 技術評論社 1991,2018")
print(" 順列 nextperm()")
print(" その他、行列式に関する本より。")
print(" 参照:https://ikatakos.com/pot/programming_algorithm/dynamic_programming/inversion")
print(" 転倒数")
print("....")
def ematrix(A):
la = np.linalg.matrix_rank(A)
print("ランク(A):",la, " , ",len(A) , "x",len(A[0])," 行列")
def test(msg, A):
print('')
print("--- 行列計算 ---", msg)
pmatrix("入力:",A)
ematrix(A)
mydet = det_det(A)
print("My det(): % 5.4f" % (mydet))
ndet = np.linalg.det(A)
if np.allclose(ndet,mydet):
print("Numpy det(): OK")
else:
print("Numpy det(): NG??", ndet)
p_header()
test("test-1",[[5]])
test("test-2",[[4,3],[1,3]])
test("test-3",[[0,-2,0],[-1,5,2],[0,-1,1]])
test("test-4",[[1,-1,-1],[-1,1,-1],[-1,-1,1]])
test("test-5",[[7,2,-4,2,3],[1,5,2,0,3],[-5,-6,3,1,2],[0,2,7,4,3],[4,2,-5,-3,5]])
test("test-6",[[1,3,9],[-1,1,-1],[2,-4,-2]])
test("test-7",[[1,9,2,12],[3,2,5,10],[2,-1,6,7],[0,6,1,7]])
#
# マトリックスがおおきいとdet_det()遅い
#
for mi in range(1,4):
mm = gen_matrix()
mn = len(mm)
m1 = " 生成行列 - %d : %d x %d " % (mi, mn, mn)
test(m1, mm)
2024-09-18 「順列生成」
行列計算で順列生成が必要になったので検索してみた。
結構な種類が見つかった。
なかでも書く行数が少ないもの。
参照:
https://stackoverflow.com/questions/104420/how-do-i-generate-all-permutations-of-a-list/
How do I generate all permutations of a list?
実行:
実行結果: 順列 = permutations() - 順列生成
参照:https://stackoverflow.com/questions/104420/how-do-i-generate-all-permutations-of-a-list/
How do I generate all permutations of a list?
....
Python itertools.permutations() ["◁","△","▽","▷"]
('◁', '△', '▽', '▷')
('◁', '△', '▷', '▽')
('◁', '▽', '△', '▷')
('◁', '▽', '▷', '△')
('◁', '▷', '△', '▽')
('◁', '▷', '▽', '△')
('△', '◁', '▽', '▷')
('△', '◁', '▷', '▽')
('△', '▽', '◁', '▷')
('△', '▽', '▷', '◁')
('△', '▷', '◁', '▽')
('△', '▷', '▽', '◁')
('▽', '◁', '△', '▷')
('▽', '◁', '▷', '△')
('▽', '△', '◁', '▷')
('▽', '△', '▷', '◁')
('▽', '▷', '◁', '△')
('▽', '▷', '△', '◁')
('▷', '◁', '△', '▽')
('▷', '◁', '▽', '△')
('▷', '△', '◁', '▽')
('▷', '△', '▽', '◁')
('▷', '▽', '◁', '△')
('▷', '▽', '△', '◁')
%%%%.. テスト1 順列生成 ..%%%%
入力: [[0, 0, 3], [1, 5, 2], [0, 1, 0]]
順列:
No. 1 - [[0, 0, 3], [1, 5, 2], [0, 1, 0]]
No. 2 - [[0, 0, 3], [0, 1, 0], [1, 5, 2]]
No. 3 - [[1, 5, 2], [0, 0, 3], [0, 1, 0]]
No. 4 - [[1, 5, 2], [0, 1, 0], [0, 0, 3]]
No. 5 - [[0, 1, 0], [1, 5, 2], [0, 0, 3]]
No. 6 - [[0, 1, 0], [0, 0, 3], [1, 5, 2]]
%%%%.. テスト2 順列生成 ..%%%%
入力: [[0, 0, 3], [1, 5, 2], [0, 1, 0]]
順列:
No. 1 - [[0, 0, 3], [1, 5, 2], [0, 1, 0]]
No. 2 - [[0, 0, 3], [0, 1, 0], [1, 5, 2]]
No. 3 - [[1, 5, 2], [0, 0, 3], [0, 1, 0]]
No. 4 - [[1, 5, 2], [0, 1, 0], [0, 0, 3]]
No. 5 - [[0, 1, 0], [0, 0, 3], [1, 5, 2]]
No. 6 - [[0, 1, 0], [1, 5, 2], [0, 0, 3]]
%%%%.. テスト3 順列生成 ..%%%%
入力: [[0, 0, 3], [1, 5, 2], [0, 1, 0]]
順列:
No. 1 - [[0, 0, 3], [1, 5, 2], [0, 1, 0]]
No. 2 - [[1, 5, 2], [0, 0, 3], [0, 1, 0]]
No. 3 - [[1, 5, 2], [0, 1, 0], [0, 0, 3]]
No. 4 - [[0, 0, 3], [0, 1, 0], [1, 5, 2]]
No. 5 - [[0, 1, 0], [0, 0, 3], [1, 5, 2]]
No. 6 - [[0, 1, 0], [1, 5, 2], [0, 0, 3]]
%%%%.. テスト6 順列生成 ..%%%%
入力: 123
順列:
No. 1 - ['1', '2', '3']
No. 2 - ['2', '1', '3']
No. 3 - ['2', '3', '1']
No. 4 - ['1', '3', '2']
No. 5 - ['3', '1', '2']
No. 6 - ['3', '2', '1']
%%%%.. テスト7 順列生成 ..%%%%
入力: ABC
順列:
No. 1 - ['A', 'B', 'C']
No. 2 - ['B', 'A', 'C']
No. 3 - ['B', 'C', 'A']
No. 4 - ['A', 'C', 'B']
No. 5 - ['C', 'A', 'B']
No. 6 - ['C', 'B', 'A']
%%%%.. テスト8 順列生成 ..%%%%
入力: ['◁', '△', '▽', '▷']
順列:
No. 1 - ['◁', '△', '▽', '▷']
No. 2 - ['◁', '△', '▷', '▽']
No. 3 - ['◁', '▽', '△', '▷']
No. 4 - ['◁', '▽', '▷', '△']
No. 5 - ['◁', '▷', '▽', '△']
No. 6 - ['◁', '▷', '△', '▽']
No. 7 - ['△', '◁', '▽', '▷']
No. 8 - ['△', '◁', '▷', '▽']
No. 9 - ['△', '▽', '◁', '▷']
No. 10 - ['△', '▽', '▷', '◁']
No. 11 - ['△', '▷', '▽', '◁']
No. 12 - ['△', '▷', '◁', '▽']
No. 13 - ['▽', '△', '◁', '▷']
No. 14 - ['▽', '△', '▷', '◁']
No. 15 - ['▽', '◁', '△', '▷']
No. 16 - ['▽', '◁', '▷', '△']
No. 17 - ['▽', '▷', '◁', '△']
No. 18 - ['▽', '▷', '△', '◁']
No. 19 - ['▷', '△', '▽', '◁']
No. 20 - ['▷', '△', '◁', '▽']
No. 21 - ['▷', '▽', '△', '◁']
No. 22 - ['▷', '▽', '◁', '△']
No. 23 - ['▷', '◁', '▽', '△']
No. 24 - ['▷', '◁', '△', '▽']
%%%%.. テスト9 順列生成 ..%%%%
入力: ['◁', '△', '▽', '▷']
順列:
No. 1 - ['◁', '△', '▽', '▷']
No. 2 - ['◁', '△', '▷', '▽']
No. 3 - ['◁', '▽', '△', '▷']
No. 4 - ['◁', '▽', '▷', '△']
No. 5 - ['◁', '▷', '△', '▽']
No. 6 - ['◁', '▷', '▽', '△']
No. 7 - ['△', '◁', '▽', '▷']
No. 8 - ['△', '◁', '▷', '▽']
No. 9 - ['△', '▽', '◁', '▷']
No. 10 - ['△', '▽', '▷', '◁']
No. 11 - ['△', '▷', '◁', '▽']
No. 12 - ['△', '▷', '▽', '◁']
No. 13 - ['▽', '◁', '△', '▷']
No. 14 - ['▽', '◁', '▷', '△']
No. 15 - ['▽', '△', '◁', '▷']
No. 16 - ['▽', '△', '▷', '◁']
No. 17 - ['▽', '▷', '◁', '△']
No. 18 - ['▽', '▷', '△', '◁']
No. 19 - ['▷', '◁', '△', '▽']
No. 20 - ['▷', '◁', '▽', '△']
No. 21 - ['▷', '△', '◁', '▽']
No. 22 - ['▷', '△', '▽', '◁']
No. 23 - ['▷', '▽', '◁', '△']
No. 24 - ['▷', '▽', '△', '◁']
%%%%.. テスト10 順列生成 ..%%%%
入力: ['◁', '△', '▽', '▷']
順列:
No. 1 - ['◁', '△', '▽', '▷']
No. 2 - ['△', '◁', '▽', '▷']
No. 3 - ['△', '▽', '◁', '▷']
No. 4 - ['△', '▽', '▷', '◁']
No. 5 - ['◁', '▽', '△', '▷']
No. 6 - ['▽', '◁', '△', '▷']
No. 7 - ['▽', '△', '◁', '▷']
No. 8 - ['▽', '△', '▷', '◁']
No. 9 - ['◁', '▽', '▷', '△']
No. 10 - ['▽', '◁', '▷', '△']
No. 11 - ['▽', '▷', '◁', '△']
No. 12 - ['▽', '▷', '△', '◁']
No. 13 - ['◁', '△', '▷', '▽']
No. 14 - ['△', '◁', '▷', '▽']
No. 15 - ['△', '▷', '◁', '▽']
No. 16 - ['△', '▷', '▽', '◁']
No. 17 - ['◁', '▷', '△', '▽']
No. 18 - ['▷', '◁', '△', '▽']
No. 19 - ['▷', '△', '◁', '▽']
No. 20 - ['▷', '△', '▽', '◁']
No. 21 - ['◁', '▷', '▽', '△']
No. 22 - ['▷', '◁', '▽', '△']
No. 23 - ['▷', '▽', '◁', '△']
No. 24 - ['▷', '▽', '△', '◁']
プログラム:
--------------permute.py -----------
"""
https://stackoverflow.com/questions/104420/how-do-i-generate-all-permutations-of-a-list/
How do I generate all permutations of a list?
"""
# -1-
def permute(xs, low=0):
if low + 1 >= len(xs):
yield xs
else:
for p in permute(xs, low + 1):
yield p
for i in range(low + 1, len(xs)):
xs[low], xs[i] = xs[i], xs[low]
for p in permute(xs, low + 1):
yield p
xs[low], xs[i] = xs[i], xs[low]
# -2-
def permutList(l):
if not l:
return [[]]
res = []
for e in l:
temp = l[:]
temp.remove(e)
res.extend([[e] + r for r in permutList(temp)])
return res
# -3-
def addperm(x,l):
return [ l[0:i] + [x] + l[i:] for i in range(len(l)+1) ]
def perm(l):
if len(l) == 0:
return [[]]
return [x for y in perm(l[1:]) for x in addperm(l[0],y) ]
# ##################################################
if __name__ == '__main__':
import itertools
def p_header():
print("実行結果: 順列 = permutations() - 順列生成")
print(" 参照:https://stackoverflow.com/questions/104420/how-do-i-generate-all-permutations-of-a-list/")
print(" How do I generate all permutations of a list?")
print("....")
f_permutation = ( permute, permutList, perm)
def test(f, msg, mL):
print("%%%%..",msg," 順列生成 ..%%%%")
print("入力:",mL)
print("順列:")
c = 1
for p in f_permutation[f](mL):
print("No.%3d - " % (c),p)
c += 1
p_header()
print('Python itertools.permutations() ["◁","△","▽","▷"]')
for v in itertools.permutations(["◁","△","▽","▷"]): print(v)
test(0,"テスト1",[[0,0,3],[1,5,2],[0,1,0]])
test(1,"テスト2",[[0,0,3],[1,5,2],[0,1,0]])
test(2,"テスト3",[[0,0,3],[1,5,2],[0,1,0]])
#test(0,"テスト4","123")
#test(1,"テスト5","123")
test(2,"テスト6","123")
test(2,"テスト7","ABC")
test(0,"テスト8",["◁","△","▽","▷"])
test(1,"テスト9",["◁","△","▽","▷"])
test(2,"テスト10",["◁","△","▽","▷"])
2024-09-17 「余因子展開逆行列計算2」
余因子展開と行列式計算を使って余因子行を作成し、それで逆行列を作る。
参照:
https://wagtail.cds.tohoku.ac.jp/coda/python/p-8-function-part2-sup-matrix.html
Pythonプログラミング(ステップ8・行列の計算) 1.行列式の計算 余因子展開による行列式計算
結果:
実行結果: 行列値 = determinant() - 行列式計算
https://wagtail.cds.tohoku.ac.jp/coda/python/p-8-function-part2-sup-matrix.html
Pythonプログラミング(ステップ8・行列の計算) 1.行列式の計算 余因子展開による行列式計算
....
■◎◎ test-1 ◎◎■
## 入力: ##
[[ 4 ]]
ランク(A): 1 , 1 x 1 行列
My det: 4
NUmpy det(): 4.0
Numpy det(): OK
## A余因子行列: ##
[[ 1 ]]
## A逆行列: ##
[[ 0.25 ]]
Numpy inv(): OK
■◎◎ test-2 ◎◎■
## 入力: ##
[[ 1 2 ]
[ 3 4 ]]
ランク(A): 2 , 2 x 2 行列
My det: -2
NUmpy det(): -2.0000000000000004
Numpy det(): OK
## A余因子行列: ##
[[ 4 -2 ]
[ -3 1 ]]
## A逆行列: ##
[[ -2 1 ]
[ 1.5 -0.5 ]]
Numpy inv(): OK
■◎◎ test-3 ◎◎■
## 入力: ##
[[ 0 -1 2 ]
[ -1 5 2 ]
[ 0 0 3 ]]
ランク(A): 3 , 3 x 3 行列
My det: -3
NUmpy det(): -3.0000000000000004
Numpy det(): OK
## A余因子行列: ##
[[ 15 3 -12 ]
[ 3 0 -2 ]
[ 0 0 -1 ]]
## A逆行列: ##
[[ -5 -1 4 ]
[ -1 -0 0.6667 ]
[ -0 -0 0.3333 ]]
Numpy inv(): OK
■◎◎ test-4 ◎◎■
## 入力: ##
[[ 5 -2 2 7 ]
[ 1 0 0 3 ]
[ -3 1 5 0 ]
[ 3 -1 -9 4 ]]
ランク(A): 4 , 4 x 4 行列
My det: 88
NUmpy det(): 88.00000000000003
Numpy det(): OK
## A余因子行列: ##
[[ -12 76 -60 -36 ]
[ -56 208 -82 -58 ]
[ 4 4 -2 -10 ]
[ 4 4 20 12 ]]
## A逆行列: ##
[[ -0.1364 0.8636 -0.6818 -0.4091 ]
[ -0.6364 2.364 -0.9318 -0.6591 ]
[ 0.04545 0.04545 -0.02273 -0.1136 ]
[ 0.04545 0.04545 0.2273 0.1364 ]]
Numpy inv(): OK
■◎◎ test-5 ◎◎■
## 入力: ##
[[ 1 -1 -1 ]
[ -1 1 -1 ]
[ -1 -1 1 ]]
ランク(A): 3 , 3 x 3 行列
My det: -4
NUmpy det(): -4.0
Numpy det(): OK
## A余因子行列: ##
[[ 0 2 2 ]
[ 2 0 2 ]
[ 2 2 0 ]]
## A逆行列: ##
[[ -0 -0.5 -0.5 ]
[ -0.5 -0 -0.5 ]
[ -0.5 -0.5 -0 ]]
Numpy inv(): OK
■◎◎ test-6 ◎◎■
## 入力: ##
[[ -1 1 1 ]
[ 1 -1 1 ]
[ 1 1 -1 ]]
ランク(A): 3 , 3 x 3 行列
My det: 4
NUmpy det(): 4.0
Numpy det(): OK
## A余因子行列: ##
[[ 0 2 2 ]
[ 2 0 2 ]
[ 2 2 0 ]]
## A逆行列: ##
[[ 0 0.5 0.5 ]
[ 0.5 0 0.5 ]
[ 0.5 0.5 0 ]]
Numpy inv(): OK
■◎◎ test-7 ◎◎■
## 入力: ##
[[ 1 3 9 ]
[ -1 1 -1 ]
[ 2 -4 -2 ]]
ランク(A): 2 , 3 x 3 行列
My det: 0
NUmpy det(): 1.1102230246251546e-15
Numpy det(): OK
逆行列はありません
■◎◎ test-8 ◎◎■
## 入力: ##
[[ -1 1 3 ]
[ 2 3 -1 ]
[ 3 4 -2 ]]
ランク(A): 2 , 3 x 3 行列
My det: 0
NUmpy det(): -1.896631000401315e-15
Numpy det(): OK
逆行列はありません
■◎◎ testC-1 ◎◎■
## 入力: ##
[[ 0 8 -5 13 ]
[ -8 -7 7 8 ]
[ 11 -4 -3 -11 ]
[ 5 8 -11 8 ]]
ランク(A): 4 , 4 x 4 行列
My det: 5317
NUmpy det(): 5317.000000000005
Numpy det(): OK
## A余因子行列: ##
[[ 1167 -4 825 -758 ]
[ 689 -663 -169 -689 ]
[ 1417 -260 455 -1417 ]
[ 530 308 279 -121 ]]
## A逆行列: ##
[[ 0.2195 -0.0007523 0.1552 -0.1426 ]
[ 0.1296 -0.1247 -0.03178 -0.1296 ]
[ 0.2665 -0.0489 0.08557 -0.2665 ]
[ 0.09968 0.05793 0.05247 -0.02276 ]]
Numpy inv(): OK
■◎◎ testC-2 ◎◎■
## 入力: ##
[[ 11 9 8 2 -3 -7 ]
[ 7 13 5 -1 -10 8 ]
[ -7 -7 -8 0 1 -4 ]
[ -10 -5 4 -10 12 -2 ]
[ 12 -10 -4 11 13 -13 ]
[ -6 -11 7 -11 -8 3 ]]
ランク(A): 6 , 6 x 6 行列
My det: 2282655
NUmpy det(): 2282655.0
Numpy det(): OK
## A余因子行列: ##
[[ -6.789e+04 5.03e+05 2.516e+05 1.449e+05 2.633e+05 7.351e+04 ]
[ 7.202e+04 5.577e+04 7.532e+04 5.501e+04 -5.952e+04 -1.015e+05 ]
[ 8.831e+04 -5.115e+05 -4.866e+05 -1.523e+05 -1.856e+05 1.537e+04 ]
[ 1.95e+04 -6.802e+05 -5.253e+05 -3.196e+05 -2.393e+05 -9.087e+04 ]
[ -7.346e+04 5.595e+04 -6.548e+04 1.156e+05 6.218e+04 -6.14e+04 ]
[ -2.022e+05 5.92e+04 -1.859e+05 -1.642e+04 3.013e+04 2916 ]]
## A逆行列: ##
[[ -0.02974 0.2204 0.1102 0.0635 0.1154 0.0322 ]
[ 0.03155 0.02443 0.033 0.0241 -0.02608 -0.04447 ]
[ 0.03869 -0.2241 -0.2132 -0.06672 -0.08133 0.006732 ]
[ 0.008541 -0.298 -0.2301 -0.14 -0.1048 -0.03981 ]
[ -0.03218 0.02451 -0.02869 0.05066 0.02724 -0.0269 ]
[ -0.08858 0.02594 -0.08145 -0.007194 0.0132 0.001277 ]]
Numpy inv(): OK
■◎◎ testC-3 ◎◎■
## 入力: ##
[[ 10 -6 -12 6 ]
[ 5 -11 -11 -8 ]
[ -7 7 -7 -8 ]
[ -10 13 -7 -11 ]]
ランク(A): 4 , 4 x 4 行列
My det: -5760
NUmpy det(): -5759.999999999993
Numpy det(): OK
## A余因子行列: ##
[[ -270 -450 3630 -2460 ]
[ -240 48 1840 -1504 ]
[ 270 -126 1170 -612 ]
[ -210 546 -1870 1372 ]]
## A逆行列: ##
[[ 0.04688 0.07812 -0.6302 0.4271 ]
[ 0.04167 -0.008333 -0.3194 0.2611 ]
[ -0.04688 0.02187 -0.2031 0.1062 ]
[ 0.03646 -0.09479 0.3247 -0.2382 ]]
Numpy inv(): OK
----
プログラム:
--------------- inv-cof3.py --------
'''
https://wagtail.cds.tohoku.ac.jp/coda/python/p-8-function-part2-sup-matrix.html
Pythonプログラミング(ステップ8・行列の計算) 1.行列式の計算 余因子展開による行列式計算
'''
def submatrix(i,j,A):
n = len(A[0])
B = [ ]
for k in range(n):
if k==i:
continue
x=[ ] # gen row vector
for l in range(n):
if l==j:
continue
x.append(A[k][l])
B.append(x)
return B
# cofactor expansion
def determinant(A):
n=len(A)
if n==1:
return A[0][0]
det=0
for i in range(n):
det = det + (-1)**(i+0) * A[i][0] * determinant(submatrix(i,0,A))
return det
# ---^^
def comatrix(A):
"""
余因子行列を作る
"""
c = len(A)
if c == 1:
# 余因子行列 1x1は、1
return [[1]]
acofctr = [[0] * c for _ in range(c)]
for i in range(c):
for j in range(c):
# 余因子行列は転置
acofctr[j][i] = (-1)**((i+j)&1) * determinant(submatrix(i, j, A))
return acofctr
def coinv(A, det):
"""
余因子行列より逆行列をつくる
"""
c = len(A)
inv = [[0] * c for _ in range(c)]
for i in range(c):
for j in range(c):
inv[i][j] = A[i][j] / det
return inv
def pmatrix(msg, MAT):
'''
行列の印刷
'''
print("##",msg,"##")
if MAT is None:
print(" 結果がありません")
return
n = len(MAT)
m = len(MAT[0])
for i in range(n):
if i == 0:
print("[[",end='')
else:
print(" [",end='')
for j in range(m):
print(" % 5.4g" % (MAT[i][j]), end='')
if i == (n-1):
print(" ]]")
else:
print(" ]")
# ####################################
if ( __name__ == '__main__' ):
import numpy as np
def p_header():
print("実行結果: 行列値 = determinant() - 行列式計算")
print(" https://wagtail.cds.tohoku.ac.jp/coda/python/p-8-function-part2-sup-matrix.html")
print(" Pythonプログラミング(ステップ8・行列の計算) 1.行列式の計算 余因子展開による行列式計算")
print("....")
def gen_matrix():
'''
行列生成 n x n
'''
import random as r
RMAX = 13
n = r.randrange(4,8)
m = []
for _ in range(n):
m.append([r.randrange(-RMAX,RMAX+1) for j in range(n)])
return m
def ematrix(A):
la = np.linalg.matrix_rank(A)
print("ランク(A):",la, " , ",len(A) , "x",len(A[0])," 行列")
def test(msg, A, EPS=1.0e-8):
print('')
print("■◎◎",msg,"◎◎■")
pmatrix("入力:",A)
ematrix(A)
mydet = determinant(A) # || ||
print("My det:",mydet)
print("NUmpy det():",np.linalg.det(A))
ndet = np.linalg.det(A)
if np.allclose(ndet,mydet):
print("Numpy det(): OK")
else:
pmatrix("Numpy det(): NG ", ndet)
if abs(mydet) < EPS:
print("逆行列はありません")
return
mymatc = comatrix(A)
pmatrix("A余因子行列:",mymatc)
myinv = coinv(mymatc, mydet)
pmatrix("A逆行列:",myinv)
ninv = np.linalg.inv(A)
if np.allclose(ninv,myinv):
print("Numpy inv(): OK")
else:
pmatrix("Munpy inv(): NG", ninv)
p_header()
test("test-1", [[4]])
test("test-2",[[1,2],[3,4]])
test("test-3", [[0,-1,2],[-1,5,2],[0,0,3]])
test("test-4", [[5, -2, 2, 7], [1, 0, 0, 3], [-3, 1, 5, 0], [3, -1, -9, 4]])
test("test-5", [[1, -1, -1],[-1, 1, -1],[-1, -1, 1]])
test("test-6", [[-1, 1, 1],[1, -1, 1],[1, 1, -1]])
test("test-7", [[1, 3, 9],[-1, 1, -1],[2, -4, -2]])
test("test-8", [[-1, 1, 3],[2, 3, -1],[3, 4, -2]])
for c in range(1,4):
test("testC-%d" % c, gen_matrix())
2024-09-12 「Doolittle法でLU分解」
Doolittle法でLU分解をやってみた。
SCIPY linalg.lu()と比べるのも何なのですが比べてみました。
ある条件では同じになります。
SCILAB 結果
>> m = [3,5,2;2,3,7;1,2,-4]
m =
3 5 2
2 3 7
1 2 -4
>> [l u p] = lu(m)
l =
1.0000 0 0
0.3333 1.0000 0
0.6667 -1.0000 1.0000
u =
3.0000 5.0000 2.0000
0 0.3333 -4.6667
0 0 1.0000
p =
Permutation Matrix
1 0 0
0 0 1
0 1 0
実行:
........
実行結果: L,U,P = doolittle() - LU分解P
https://johnfoster.pge.utexas.edu/numerical-methods-book/LinearAlgebra_LU.html
doolittle()
....
[@@@@@@@@@@@@@@@@@@] testA-1,2,3 [@@@@@@@@@@@@@@@@@@]
入力:
[[3, 5, 2], [2, 3, 7], [1, 2, -4]]
答:
ランク(A): 3 3 x 3 行列
### sci lu().U: ###
3.00000 5.00000 2.00000
0.00000 0.33333 -4.66667
0.00000 0.00000 1.00000
### sci lu().U: ###
1.00000 0.00000 0.00000
0.33333 1.00000 0.00000
0.66667 -1.00000 1.00000
scipy lu() Up: Ng?
scipy lu() Low: Ng?
### U1: ###
3.00000 5.00000 2.00000
0.00000 -0.33333 5.66667
0.00000 0.00000 1.00000
### L1: ###
1.00000 0.00000 0.00000
0.66667 1.00000 0.00000
0.33333 -1.00000 1.00000
[[ 3. 5. 2.]
[ 2. 3. 7.]
[ 1. 2. -4.]]
行入れ替え情報: [0, 1, 2]
DET: -1.000000000000007
Scipy lu() det: -1.000000000000007
numpy det: -1.0000000000000047
..検算..
det() OK
matrix OK
[@@@@@@@@@@@@@@@@@@] testA-1,3,2 [@@@@@@@@@@@@@@@@@@]
入力:
[[3, 5, 2], [1, 2, -4], [2, 3, 7]]
答:
ランク(A): 3 3 x 3 行列
### sci lu().U: ###
3.00000 5.00000 2.00000
0.00000 0.33333 -4.66667
0.00000 0.00000 1.00000
### sci lu().U: ###
1.00000 0.00000 0.00000
0.33333 1.00000 0.00000
0.66667 -1.00000 1.00000
scipy lu() Up: OK
scipy lu() Low: OK
### U1: ###
3.00000 5.00000 2.00000
0.00000 0.33333 -4.66667
0.00000 0.00000 1.00000
### L1: ###
1.00000 0.00000 0.00000
0.33333 1.00000 0.00000
0.66667 -1.00000 1.00000
[[ 3. 5. 2.]
[ 1. 2. -4.]
[ 2. 3. 7.]]
行入れ替え情報: [0, 1, 2]
DET: 1.0000000000000067
Scipy lu() det: 1.0000000000000067
numpy det: 1.0000000000000047
..検算..
det() OK
matrix OK
[@@@@@@@@@@@@@@@@@@] testA-2,1,3 [@@@@@@@@@@@@@@@@@@]
入力:
[[2, 3, 7], [3, 5, 2], [1, 2, -4]]
答:
ランク(A): 3 3 x 3 行列
### sci lu().U: ###
3.00000 5.00000 2.00000
0.00000 0.33333 -4.66667
0.00000 0.00000 1.00000
### sci lu().U: ###
1.00000 0.00000 0.00000
0.33333 1.00000 0.00000
0.66667 -1.00000 1.00000
scipy lu() Up: Ng?
scipy lu() Low: Ng?
### U1: ###
3.00000 5.00000 2.00000
0.00000 -0.33333 5.66667
0.00000 0.00000 1.00000
### L1: ###
1.00000 0.00000 0.00000
0.66667 1.00000 0.00000
0.33333 -1.00000 1.00000
[[ 3. 5. 2.]
[ 2. 3. 7.]
[ 1. 2. -4.]]
行入れ替え情報: [1, 0, 2]
DET: 1.000000000000007
Scipy lu() det: 1.000000000000007
numpy det: 1.0000000000000047
..検算..
det() OK
matrix OK
[@@@@@@@@@@@@@@@@@@] testA-2,3,1 [@@@@@@@@@@@@@@@@@@]
入力:
[[2, 3, 7], [1, 2, -4], [3, 5, 2]]
答:
ランク(A): 3 3 x 3 行列
### sci lu().U: ###
3.00000 5.00000 2.00000
0.00000 0.33333 -4.66667
0.00000 0.00000 1.00000
### sci lu().U: ###
1.00000 0.00000 0.00000
0.33333 1.00000 0.00000
0.66667 -1.00000 1.00000
scipy lu() Up: OK
scipy lu() Low: OK
### U1: ###
3.00000 5.00000 2.00000
0.00000 0.33333 -4.66667
0.00000 0.00000 1.00000
### L1: ###
1.00000 0.00000 0.00000
0.33333 1.00000 0.00000
0.66667 -1.00000 1.00000
[[ 3. 5. 2.]
[ 1. 2. -4.]
[ 2. 3. 7.]]
行入れ替え情報: [2, 1, 0]
DET: -1.0000000000000067
Scipy lu() det: -1.0000000000000067
numpy det: -1.0000000000000047
..検算..
det() OK
matrix OK
[@@@@@@@@@@@@@@@@@@] testA-3,1,2 [@@@@@@@@@@@@@@@@@@]
入力:
[[1, 2, -4], [3, 5, 2], [2, 3, 7]]
答:
ランク(A): 3 3 x 3 行列
### sci lu().U: ###
3.00000 5.00000 2.00000
0.00000 0.33333 -4.66667
0.00000 0.00000 1.00000
### sci lu().U: ###
1.00000 0.00000 0.00000
0.33333 1.00000 0.00000
0.66667 -1.00000 1.00000
scipy lu() Up: OK
scipy lu() Low: OK
### U1: ###
3.00000 5.00000 2.00000
0.00000 0.33333 -4.66667
0.00000 0.00000 1.00000
### L1: ###
1.00000 0.00000 0.00000
0.33333 1.00000 0.00000
0.66667 -1.00000 1.00000
[[ 3. 5. 2.]
[ 1. 2. -4.]
[ 2. 3. 7.]]
行入れ替え情報: [1, 0, 2]
DET: -1.0000000000000067
Scipy lu() det: -1.0000000000000067
numpy det: -1.0000000000000047
..検算..
det() OK
matrix OK
[@@@@@@@@@@@@@@@@@@] testA-3,2,1 [@@@@@@@@@@@@@@@@@@]
入力:
[[1, 2, -4], [2, 3, 7], [3, 5, 2]]
答:
ランク(A): 3 3 x 3 行列
### sci lu().U: ###
3.00000 5.00000 2.00000
0.00000 0.33333 -4.66667
0.00000 0.00000 1.00000
### sci lu().U: ###
1.00000 0.00000 0.00000
0.33333 1.00000 0.00000
0.66667 -1.00000 1.00000
scipy lu() Up: Ng?
scipy lu() Low: Ng?
### U1: ###
3.00000 5.00000 2.00000
0.00000 -0.33333 5.66667
0.00000 0.00000 1.00000
### L1: ###
1.00000 0.00000 0.00000
0.66667 1.00000 0.00000
0.33333 -1.00000 1.00000
[[ 3. 5. 2.]
[ 2. 3. 7.]
[ 1. 2. -4.]]
行入れ替え情報: [2, 1, 0]
DET: 1.000000000000007
Scipy lu() det: 1.000000000000007
numpy det: 1.0000000000000047
..検算..
det() OK
matrix OK
TEST MATRIX No. 1
15 x 15 行列
ランク(A): 15 15 x 15 行列
..検算:
scipy lu() Up: OK
scipy lu() Low: OK
det() OK
scipy lu() det: OK
matrix OK
TEST MATRIX No. 2
19 x 19 行列
ランク(A): 19 19 x 19 行列
..検算:
scipy lu() Up: OK
scipy lu() Low: OK
det() OK
scipy lu() det: OK
matrix OK
TEST MATRIX No. 3
18 x 18 行列
ランク(A): 18 18 x 18 行列
..検算:
scipy lu() Up: OK
scipy lu() Low: OK
det() OK
scipy lu() det: OK
matrix OK
TEST MATRIX No. 4
17 x 17 行列
ランク(A): 17 17 x 17 行列
..検算:
scipy lu() Up: OK
scipy lu() Low: OK
det() OK
scipy lu() det: OK
matrix OK
TEST MATRIX No. 5
28 x 28 行列
ランク(A): 28 28 x 28 行列
..検算:
scipy lu() Up: OK
scipy lu() Low: OK
det() OK
scipy lu() det: OK
matrix OK
....
プログラム:
'''
掃き出し法 上三角行列で行列式計算
https://stackoverflow.com/questions/40887409/numpy-matrix-determinant-precision-problems
Numpy matrix determinant precision problems
'''
def my_det(mX,n, EPS=1.0e-7):
X = [mX[i][:n] for i in range(n)]
s = 1
for i in range(n):
maxElement = abs(X[i][i])
maxRow = i
for k in range(i + 1, n):
if abs(X[k][i]) > maxElement:
maxElement = abs(X[k][i])
maxRow = k
if maxRow != i:
s = -s
for k in range(i, n):
xt = X[i][k]
X[i][k] = X[maxRow][k]
X[maxRow][k] = xt
if abs(X[i][i]) < EPS:
return 0
for k in range(i + 1, n):
c = -X[k][i] / X[i][i]
for j in range(i, n):
if i == j:
X[k][j] = 0
else:
X[k][j] += c * X[i][j]
det = 1
for i in range(n):
det *= X[i][i]
det *= s
return det
def check_submatrix(A,P,n,eps):
pv = abs(A[0][0]) # 先頭に絶対値最大設定
ii = 0
for x in range(1,n):
ab = abs(A[x][0])
if ab > pv:
pv = ab
ii = x
if 0 != ii:
for j in range(n):
xx = A[0][j]
A[0][j] = A[ii][j]
A[ii][j] = xx
xx = P[0]
P[0] = P[ii]
P[ii] = xx
for i in range(1,n): # 2行目以降、首座小行列式のゼロ検出したら行入れ替え
sdet = my_det(A,i+1)
if abs(sdet) < eps:
if (i + 1) == n:
return False
for j in range(n):
xx = A[i][j]
A[i][j] = A[i+1][j]
A[i+1][j] = xx
xx = P[i]
P[i] = P[i+1]
P[i+1] = xx
return True
'''
https://johnfoster.pge.utexas.edu/numerical-methods-book/LinearAlgebra_LU.html
'''
def exe_doolittle(A,P, n, eps):
U = [ [0 for _ in range(n)] for _ in range(n)]
L = [ [ 0 if i!=j else 1 for j in range(n)] for i in range(n) ]
for k in range(n):
#nU[k, k:] = nA[k, k:] - nL[k,:k] @ nU[:k,k:]
for j in range(k, n):
sum = 0
for d in range(k):
sum += L[k][d] * U[d][j]
if k == j and (A[k][j] - sum) < eps:
pass
U[k][j] = A[k][j] - sum
#nL[(k+1):,k] = (nA[(k+1):,k] - nL[(k+1):,:] @ nU[:,k]) / nU[k, k]
if abs(U[k][k]) < eps:
return None,None,None
for i in range(k+1, n):
sum = 0
for d in range(n):
sum += L[i][d] * U[d][k]
L[i][k] = ( A[i][k] - sum) / U[k][k]
return L,U,P
def doolittle(Amt, EPS=1.0e-7):
n = len(Amt)
A = [e.copy() for e in Amt]
P = [_ for _ in range(n)]
if check_submatrix(A,P,n,EPS):
return exe_doolittle(A,P,n,EPS)
return None,None,None
def doolittle_direct(Amt, EPS=1.0e-7):
n = len(Amt)
A = [e.copy() for e in Amt]
P = [_ for _ in range(n)]
return exe_doolittle(A,P,n,EPS)
'''
----^^^^^
'''
def matrix_dmp(msg, A):
print("### ",msg," ###")
n = len(A)
for i in range(n):
for j in range(n):
print(" % 0.5f" % (A[i][j]), end='')
print("")
def chk(a):
if type(a) == list:
if len(a) == 0:
return None
else:
if type(a[0]) != list:
A = [a.copy()]
else:
A = [e.copy() for e in a]
n = len(A)
m = len(A[0])
else:
n = 0
m = 0
if m != n or n == 0: # 正方行列のみ
return None
return A
if __name__ == '__main__':
import numpy as np
from scipy.linalg import lu as slu
def p_header():
print("実行結果: L,U,P = doolittle() - LU分解P")
print(" https://johnfoster.pge.utexas.edu/numerical-methods-book/LinearAlgebra_LU.html")
print(" doolittle()")
print("....")
def ematrix(PA):
if type(PA) == list:
if type(PA[0]) != list:
A = [PA.copy()]
else:
A = [e.copy() for e in PA]
n = len(A)
m = len(A[0])
else:
n = 0
m = 0
if m != n or m == 0: # 右辺はなし、正方行列
print("答なし ")
return
la = np.linalg.matrix_rank(A)
print("ランク(A):",la, " ",n,"x",n," 行列")
def permutation(P, mat):
'''
順列 交換回数計算
'''
n = len(P)
Z = [e for e in P]
cnt = 0
for i in range(n):
if Z[i] != i:
min = i
for j in range(i+1,n):
if Z[j] < Z[min]:
min = j
for j in range(n):
xx = mat[min][j]
mat[min][j] = mat[i][j]
mat[i][j] = xx
xx = Z[min]
Z[min] = Z[i]
Z[i] = xx
cnt += 1
return cnt
def mpermutation(mP):
'''
順列行列 交換回数計算
'''
n = len(mP)
P = [e.copy() for e in mP]
cnt = 0
for i in range(n):
if P[i][i] != 1:
cnt += 1
for j in range(i+1,n):
if P[j][i] == 1:
for k in range(n):
ss = P[i][k]
P[i][k] = P[j][k]
P[j][k] = ss
break
return cnt
def gen_matrix(n=0, RMAX=50, DCP=1):
'''
行列生成 N x N
n = 0 : ランダムNxN , 9 : 9 x 9行列
RMAX = 50 : (+-50)で要素データ、 99: (+-99)で要素データ
DCP = 1 : 要素データ * 10, +9 : 要素データ * (10**9) 、 -9 : 要素データ / (10**9)
'''
import random as r
DC = 10**abs(DCP)
if n == 0:
N = r.randrange(10,41) # 10x10 ~ 40x40の行列を作る
else:
N = n # n x n の行列を作る
nx = r.randrange(N*4) # 時々、対角優位行列でなくする
m = []
for i in range(N):
m.append([r.randrange(-RMAX,RMAX+1) for j in range(N)])
for i in range(N):
if i != nx:
ml = 0
for j in range(N):
if i != j:
ml += abs(m[i][j])
if m[i][i] < 0:
m[i][i] -= ml
else:
m[i][i] += ml
for i in range(N):
for j in range(N):
if DCP < 0:
m[i][j] /= DC
else:
m[i][j] *= DC
return m
def testMatrix(nc, EPS=1.0e-7):
for n in range(1, nc+1):
print("")
print("TEST MATRIX No.", n)
A = gen_matrix(RMAX=360, DCP=-3)
nn = len(A)
print(" %d x %d 行列" % (nn,nn))
ematrix(A)
L1,U1,P1 = doolittle(A)
if L1 is None: # 左辺行列がない
print(" 計算できません")
else:
print("..検算:")
P2, L2,U2 = slu(A)
sdet = 1
for i in range(len(P2)):
sdet *= U2[i][i]
sdet *= (-1)**mpermutation(P2)
if np.allclose(U1,U2):
print("scipy lu() Up: OK")
else:
print("scipy lu() Up: Ng?")
if np.allclose(L1,L2):
print("scipy lu() Low: OK")
else:
print("scipy lu() Low: Ng?")
lxu = np.dot(L1,U1)
det = 1
for i in range(len(A)):
det *= U1[i][i]
s = permutation(P1, lxu)
if s & 1:
det = -det
if abs(det) < EPS:
print(" DET() == ZERO")
ndet = np.linalg.det(A)
if np.allclose(det, ndet):
print(" det() OK")
else:
print(" det() ??NG")
if np.allclose(sdet, det):
print(" scipy lu() det: OK")
else:
print(" scipy lu() det: ??NG")
if np.allclose(A, lxu):
print(" matrix OK")
else:
print(" matrix ??NG")
def test(msg,mat, EPS=1.0e-7):
print("")
print("[@@@@@@@@@@@@@@@@@@]",msg,"[@@@@@@@@@@@@@@@@@@]")
print("入力:")
print(mat)
print("答:")
A = chk(mat)
if A is None: # 左辺行列がない
print("計算できません")
return
ematrix(mat)
L1,U1,P1 = doolittle(A)
if L1 is None: # 左辺行列が可逆行列でない
print(" 計算できません")
else:
P2, L2,U2 = slu(A)
matrix_dmp("sci lu().U:",U2)
matrix_dmp("sci lu().U:",L2)
det = 1
for i in range(len(P2)):
det *= U2[i][i]
det *= (-1)**mpermutation(P2)
if np.allclose(U1,U2):
print("scipy lu() Up: OK")
else:
print("scipy lu() Up: Ng?")
if np.allclose(L1,L2):
print("scipy lu() Low: OK")
else:
print("scipy lu() Low: Ng?")
matrix_dmp("U1:",U1)
matrix_dmp("L1:",L1)
lxu = np.dot(L1,U1)
print(lxu)
print("行入れ替え情報:", P1)
det = 1
for i in range(len(A)):
det *= U1[i][i]
s = permutation(P1, lxu)
if s & 1:
det = -det
print("DET:",det)
if abs(det) < EPS:
print(" DET() == ZERO")
print("Scipy lu() det:",det)
ndet = np.linalg.det(A)
print("numpy det:",ndet)
print("..検算..")
if np.allclose(det, ndet):
print(" det() OK")
else:
print(" det() ??NG")
#matrix_dmp("my L@U:",lxu)
if np.allclose(A, lxu):
print(" matrix OK")
else:
print(" matrix ??NG", lxu)
p_header()
test("testA-1,2,3",[[3,5,2],[2,3,7],[1,2,-4]]) # 1,2,3
test("testA-1,3,2",[[3,5,2],[1,2,-4],[2,3,7]]) # 1,3,2
test("testA-2,1,3",[[2,3,7],[3,5,2],[1,2,-4]]) # 2,1,3
test("testA-2,3,1",[[2,3,7],[1,2,-4],[3,5,2]]) # 2,3,1
test("testA-3,1,2",[[1,2,-4],[3,5,2],[2,3,7]]) # 3,1,2
test("testA-3,2,1",[[1,2,-4],[2,3,7],[3,5,2]]) # 3,2,1
testMatrix(5)
#test("testB-1.2.3",[[0,0,3],[-1,5,2],[0,-1,0]]) # 1,2,3
#test("testB-1,3,2",[[0,0,3],[0,-1,0],[-1,5,2]]) # 1,3,2
#test("testB-2,1,3",[[-1,5,2],[0,0,3],[0,-1,0]]) # 2,1,3
#test("testB-2,3,1",[[-1,5,2],[0,-1,0],[0,0,3]]) # 2,3,1
#test("testB-3,1,2",[[0,-1,0],[0,0,3],[-1,5,2]]) # 3,1,2
#test("testB-3,2,1",[[0,-1,0],[-1,5,2],[0,0,3]]) # 3,2,1
2024-09-03 「Gauss-Jordan消去・完全ピポッド法」
参照:パソコンBASIC数値計算Ⅰ 小島紀夫、町田東一著 東海大学出版会 1982,1994
2.1.5 完全ピポッド法のプログラム
Gauss-Jordan消去法での完全ピポッドのプログラム。
実行:
...
実行結果: 答 = gl_complete_pivot(AB,DET=行列計算値) - Gauss-Jordan 完全ピボット
本 パソコンBASIC数値計算Ⅰ 小島紀夫、町田東一著 東海大学出版会 1982,1994
2.1.5 完全ピポッド法のプログラム
....
◆◆◆◆ 計算1 ◆◆◆◆
入力: MATRIX:
[ 2 | 3 ]
ランク (A): 1
ランク(AB): 1
答は一つ : ランク(A) == ランク(AB) == A行数 1 x 1 行列
答: MATRIX:
[ 1.5 ]
== numpy solve(): OK
◆◆◆◆ 計算2 ◆◆◆◆
入力: MATRIX:
[ 1 0.99 | 1.99 ]
[ 0.99 0.98 | 1.97 ]
ランク (A): 2
ランク(AB): 2
答は一つ : ランク(A) == ランク(AB) == A行数 2 x 2 行列
答: MATRIX:
[ 1 ]
[ 1 ]
== numpy solve(): OK
◆◆◆◆ 計算3 ◆◆◆◆
入力: MATRIX:
[ 0 1 3 0 | 1 ]
[ 1 0 2 4 | 0 ]
[ 0 0 0 1 | 0 ]
[ 5 -4 -4 0 | 0 ]
ランク (A): 4
ランク(AB): 4
答は一つ : ランク(A) == ランク(AB) == A行数 4 x 4 行列
答: MATRIX:
[ 4 ]
[ 7 ]
[ -2 ]
[ 2.78e-17 ]
== numpy solve(): OK
◆◆◆◆ 計算4 ◆◆◆◆
入力: MATRIX:
[ 2.08 3.4 1.04 -0.28 | 1.28 ]
[ -1.68 -2.68 -0.84 0.16 | -6.72 ]
[ 5.14 3.12 -4.32 4.59 | 0.86 ]
[ 3.12 2.8 1.56 1.88 | 4.62 ]
ランク (A): 3
ランク(AB): 4
答はなし : ランク(A) < ランク(AB) 4 x 4 行列
計算できません
◆◆◆◆ 逆行列計算1 ◆◆◆◆
入力: MATRIX:
[ 0 2 | 1 0 ]
[ 5 0 | 0 1 ]
ランク (A): 2
ランク(AB): 2
答は一つ : ランク(A) == ランク(AB) == A行数 2 x 2 行列
答: MATRIX:
[ 0 0.2 ]
[ 0.5 0 ]
== numpy inv(): OK
◆◆◆◆ 逆行列計算2 ◆◆◆◆
入力: MATRIX:
[ -1 1 1 | 1 0 0 ]
[ 1 -1 1 | 0 1 0 ]
[ 1 1 -1 | 0 0 1 ]
ランク (A): 3
ランク(AB): 3
答は一つ : ランク(A) == ランク(AB) == A行数 3 x 3 行列
答: MATRIX:
[ 0 0.5 0.5 ]
[ 0.5 0 0.5 ]
[ 0.5 0.5 0 ]
== numpy inv(): OK
◆◆◆◆ 逆行列計算3 ◆◆◆◆
入力: MATRIX:
[ 1 3 9 | 1 0 0 ]
[ -1 1 -1 | 0 1 0 ]
[ 2 -4 -2 | 0 0 1 ]
ランク (A): 2
ランク(AB): 3
答はなし : ランク(A) < ランク(AB) 3 x 3 行列
計算できません
◆◆◆◆ 逆行列計算4 ◆◆◆◆
入力: MATRIX:
[ 2 | 1 ]
ランク (A): 1
ランク(AB): 1
答は一つ : ランク(A) == ランク(AB) == A行数 1 x 1 行列
答: MATRIX:
[ 0.5 ]
== numpy inv(): OK
◆◆◆◆ 逆行列計算5 ◆◆◆◆
入力: MATRIX:
[ 2 -4 0 | 1 0 0 ]
[ 3 -6 -2 | 0 1 0 ]
[ 1 -2 1 | 0 0 1 ]
ランク (A): 2
ランク(AB): 3
答はなし : ランク(A) < ランク(AB) 3 x 3 行列
計算できません
◆◆◆◆ 逆行列計算6 ◆◆◆◆
入力: MATRIX:
[ -6 -2 -9 -2 | 1 0 0 0 ]
[ -10 3 -8 11 | 0 1 0 0 ]
[ 7 -9 -9 5 | 0 0 1 0 ]
[ -11 8 5 5 | 0 0 0 1 ]
ランク (A): 4
ランク(AB): 4
答は一つ : ランク(A) == ランク(AB) == A行数 4 x 4 行列
答: MATRIX:
[ -0.13 0.149 -0.137 -0.243 ]
[ -0.157 0.298 -0.326 -0.392 ]
[ 0.0235 -0.17 0.148 0.236 ]
[ -0.0583 0.0213 0.0717 0.0581 ]
== numpy inv(): OK
--------------------------
プログラム:
------------- gj-complete-pivot.py --------------
'''
本 パソコンBASIC数値計算Ⅰ 小島紀夫、町田東一著 東海大学出版会 1982,1994
2.1.5 完全ピポッド法のプログラム
'''
def gj_complete_pivot(PA,DET=None,E=1.0E-5):
'''
Gauss-Jordan消去法 完全ピポッド法
入力: 左辺行列+右辺行列
行列式計算結果域 []
出力: 答行列
行列式計算結果域に結果
'''
A = [e.copy() for e in PA]
n = len(A)
m = len(A[0])
L = [_ for _ in range(n)]
SD = 1
for k in range(n):
sw = abs(A[k][k])
iw = k
jw = k
for j in range(k,n):
for i in range(k,n):
if sw < abs(A[i][j]):
sw = abs(A[i][j])
iw = i
jw = j
if sw < E:
return None
if k != iw:
SD = -SD
for j in range(k,m):
sw = A[k][j]
A[k][j] = A[iw][j]
A[iw][j] = sw
if k != jw:
SD = -SD
for i in range(n):
sw = A[i][k]
A[i][k] = A[i][jw]
A[i][jw] = sw
mw = L[k]
L[k] = L[jw]
L[jw] = mw
sw = A[k][k]
if abs(sw) < E:
return None
SD *= sw
kw = k +1
for j in range(kw,m):
A[k][j] /= sw
for i in range(n):
if i != k:
sw = A[i][k]
for j in range(kw,m):
A[i][j] -= sw * A[k][j]
# 答を行入れ替え前に戻す
nw = n
for j in range(nw,m):
sv = [e[j] for e in A]
for i in range(n):
ww = L[i]
A[ww][j] = sv[i]
if DET != None:
DET[0] = SD
return [e[n:] for e in A]
def matrix_dmp(msg, MAT):
'''
行列の印刷
'''
print(msg, " MATRIX:")
if MAT is None:
print(" 結果がありません")
return
if len(MAT) == 0:
A: list = [[]]
else:
if type(MAT[0]) == list:
A = [e.copy() for e in MAT]
else:
A = [MAT]
n = len(A)
nm = len(A[0])
for i in range(n):
print("[",end='')
if nm <= n:
for j in range(nm):
print(" % 8.3g" % (A[i][j]), end='')
else:
for j in range(n):
print(" % 8.3g" % (A[i][j]), end='')
print(" |",end='')
for j in range(n,nm):
print(" % 8.3g" % (A[i][j]), end='')
print(" ]")
def chk(m):
if type(m) == list:
if len(m) == 0:
return None
else:
if type(m[0]) != list:
A = [m.copy()]
else:
A = [e.copy() for e in m]
n = len(A)
m = len(A[0])
else:
n = 0
m = 0
if m > (n*2) or m == 0: # 右辺は行数と同じ列数まで
return None
return A
if __name__ == '__main__':
import numpy as np
def p_header():
print("実行結果: 答 = gl_complete_pivot(AB,DET=行列計算値) - Gauss-Jordan 完全ピボット")
print(" 本 パソコンBASIC数値計算Ⅰ 小島紀夫、町田東一著 東海大学出版会 1982,1994")
print(" 2.1.5 完全ピポッド法のプログラム")
print("....")
def ematrix(A):
n = len(A)
ma = []
for i in range(n):
ma.append(A[i][:n])
la = np.linalg.matrix_rank(ma)
lab = np.linalg.matrix_rank(A)
print("ランク (A):",la)
print("ランク(AB):",lab)
if la == lab and la == n:
print("答は一つ : ランク(A) == ランク(AB) == A行数 ",n,"x",n," 行列")
elif la == lab and la < n:
print("答は無限 : ランク(A) == ランク(AB) < A行数",n,"x",n," 行列")
else:
print("答はなし : ランク(A) < ランク(AB)",n,"x",n," 行列")
def check_inv(A,am,det):
n = len(A)
if am is None or n == 0:
return
if type(A[0]) == list:
MA = [e[:n] for e in A]
Mb = [e[n:] for e in A]
else:
n = 1
MA = [A[:n]]
Mb = [A[n:]]
if det != None:
ndet = np.linalg.det(MA)
if np.allclose(ndet,det):
print(" == numpy det(): OK")
else:
print(" != numpy det() : NG??", ndet)
ti = 1
if len(MA[0]) == len(Mb[0]):
#
# (注意)同じ列数の右辺に単位列を定義したら逆行列として検算をする。
#
for i in range(n):
if float(Mb[i][i]) != 1.0:
ti = 0
break
for j in range(len(Mb[0])):
if i != j and float(Mb[i][j]) != 0.0:
ti = 0
break
else:
ti = 0
if ti:
ninv = np.linalg.inv(MA)
if np.allclose(ninv, am):
print(" == numpy inv(): OK")
else:
matrix_dmp(" != numpy inv(): NG??:",ninv)
else:
nslv = np.linalg.solve(MA,Mb)
if np.allclose(nslv,am):
print(" == numpy solve(): OK")
else:
matrix_dmp(" != numpy solve(): NG??", nslv.tolist())
def test1(msg,A):
print("◆◆◆◆",msg,"◆◆◆◆")
matrix_dmp("入力:",A)
A = chk(A)
if A is None:
print("計算できません")
return
if len(A) == len(A[0]):
print("方程式の答はありません")
return
ematrix(A)
det = None
am = gj_complete_pivot(A,DET=det)
if am is None:
print("計算できません")
return
matrix_dmp(" 答:", am)
if det != None:
adet = det[0]
print(" Det: % .5f" % (adet))
check_inv(A,am,adet)
else:
adet = 0;
check_inv(A,am,None)
p_header()
test1("計算1",[[2,3]])
test1("計算2",[[1,0.99,1.99],[0.99,0.98,1.97]])
test1("計算3",[[0, 1, 3, 0,1], [1, 0, 2, 4,0], [0, 0, 0, 1,0], [5, -4, -4, 0,0]])
test1("計算4",[[2.08,3.4,1.04,-0.28,1.28],[-1.68,-2.68,-0.84,0.16,-6.72],[5.14,3.12,-4.32,4.59,0.86],[3.12,2.8,1.56,1.88,4.62]])
test1("逆行列計算1",[[0,2,1,0],[5,0,0,1]])
test1("逆行列計算2",[[-1,1,1,1,0,0],[1,-1,1,0,1,0],[1,1,-1,0,0,1]])
test1("逆行列計算3",[[1,3,9,1,0,0],[-1,1,-1,0,1,0],[2,-4,-2,0,0,1]])
test1("逆行列計算4",[2,1])
test1("逆行列計算5",[[2,-4,0,1,0,0],[3,-6,-2,0,1,0],[1,-2,1,0,0,1]])
test1("逆行列計算6",[[-6,-2,-9,-2,1,0,0,0],[-10,3,-8,11,0,1,0,0],[7,-9,-9,5,0,0,1,0],[-11,8,5,5,0,0,0,1]])
2024-08-31 「CROUT法LU分解」
参考:https://johnfoster.pge.utexas.edu/numerical-methods-book/LinearAlgebra_LU.html
のなかの
crout
https://qiita.com/Sharkkii/items/47bbd6b0360a8431a316
チョットワカル【LU分解】
LU分解可能であるための条件(命題) 図を参照
Numerical Recipes in C Second Edition
Chapter 2. Solution of Linear Algebraic Equations
ludcmp() , lubksb()
https://stackoverflow.com/questions/5690010/lu-decomposition-from-numerical-recipes-not-working-what-am-i-doing-wrong
LU Decomposition from Numerical Recipes not working; what am I doing wrong?
・・・
参考の1番目のcrout法のLU分解では、[[1, 2, 3], [2, 4, 8], [4, 1, 1]] の処理中にゼロデバイドでエラーになり分解されない。
....
import numpy as np
def crout(A):
n = A.shape[0]
U = np.zeros((n, n), dtype=np.double)
L = np.zeros((n, n), dtype=np.double)
for k in range(n):
L[k, k] = A[k, k] - L[k, :] @ U[:, k]
U[k, k:] = (A[k, k:] - L[k, :k] @ U[:k, k:]) / L[k, k]
L[(k+1):, k] = (A[(k+1):, k] - L[(k+1):, :] @ U[:, k]) / U[k, k]
return L, U
A = np.array([[1, 2, 3], [2, 4, 8], [4, 1, 1]])
L, U = crout(A)
print(L,U)
......
結果:
crout3.py:14: RuntimeWarning: divide by zero encountered in divide
U[k, k:] = (A[k, k:] - L[k, :k] @ U[:k, k:]) / L[k, k]
crout3.py:14: RuntimeWarning: invalid value encountered in divide
U[k, k:] = (A[k, k:] - L[k, :k] @ U[:k, k:]) / L[k, k]
[[ 1. 0. 0.]
[ 2. 0. 0.]
[ 4. nan nan]] [[ 1. 2. 3.]
[ 0. nan inf]
[ 0. 0. nan]]
...............
ほかのcrout法のプログラムもやってみたが同じようであった。
分解できない判定方法はあるのだろうか?
参考:チョットワカル【LU分解】 のLU分解可能であるための条件(命題)より
LU分解できる条件は首座小行列式が零でないということだそう。
[1, 2, 3] 1行目 [1], 2行目 [1,2]
[2, 4, 8] [2,4]
[4, 1, 1] 式=1 式= 0
[1, 2, 3] 1行目 [1], 2行目 [1,2], 3行目
[4, 1, 1] [4,1]
[2, 4, 8] 式=1 式= -7 式= -14
[0, 0, 3] 1行目 [0]
[-1,5, 2]
[0,-1, 2] 式=0
[-1,5, 2] 1行目 [-1], 2行目 [-1,5]
[ 0,0, 3] [ 0,0]
[0,-1, 2] 式=-1 式= 0
[-1,5, 2] 1行目 [-1], 2行目 [-1,5], 3行目
[0,-1, 2] [0,-1]
[0, 0, 3] 式=-1 式= 1 式= 3
ならば、行を入れ替えればLU分解はできるので納得。
もし結果がおかしいとなったら、行列の行入れ替えが起きたかどうかと、首座小行列式が零でないことをチェックする、
前のはあまりに良くなかったので、以下は定番のNumerical Recipeから。
実行:
------------
実行結果: LU,index,det-sign, ps, 行入れ替え = ludcmpt() - LU分解Mix
(参照1) Numerical Recipes in C Second Edition
Chapter 2. Solution of Linear Algebraic Equations
ludcmp() , lubksb()
(参照2) https://stackoverflow.com/questions/5690010/lu-decomposition-from-numerical-recipes-not-working-what-am-i-doing-wrong
LU Decomposition from Numerical Recipes not working; what am I doing wrong?
....
■◎◎ crout−1a ◎◎■
入力 A: [[1, 2, 3], [2, 4, 8], [4, 1, 1]]
ランク(A): 3 , 3 x 3 行列
## My逆行列 ##
[ -0.2857 0.0714 0.2857 ]
[ 2.1429 -0.7857 -0.1429 ]
[ -1.0000 0.5000 0.0000 ]
## 検算: ##
[ 1.0000 0.0000 0.0000 ]
[ 0.0000 1.0000 0.0000 ]
[ 0.0000 0.0000 1.0000 ]
= numpy.inv()に等しい
My det(): 14.0
numpy det(): 14.000000000000004
..LU分離検算..
XA: [[1. 2. 3.]
[2. 4. 8.]
[4. 1. 1.]]
A: [[1, 2, 3], [2, 4, 8], [4, 1, 1]]
P@L@U == A : OK
■◎◎ crout−1b ◎◎■
入力 A: [[2, 4, 8], [1, 2, 3], [4, 1, 1]]
ランク(A): 3 , 3 x 3 行列
## My逆行列 ##
[ 0.0714 -0.2857 0.2857 ]
[ -0.7857 2.1429 -0.1429 ]
[ 0.5000 -1.0000 0.0000 ]
## 検算: ##
[ 1.0000 0.0000 0.0000 ]
[ 0.0000 1.0000 -0.0000 ]
[ 0.0000 0.0000 1.0000 ]
= numpy.inv()に等しい
My det(): -14.0
numpy det(): -14.000000000000004
..LU分離検算..
XA: [[2. 4. 8.]
[1. 2. 3.]
[4. 1. 1.]]
A: [[2, 4, 8], [1, 2, 3], [4, 1, 1]]
P@L@U == A : OK
■◎◎ crout−1c ◎◎■
入力 A: [[4, 1, 1], [1, 2, 3], [2, 4, 8]]
ランク(A): 3 , 3 x 3 行列
## My逆行列 ##
[ 0.2857 -0.2857 0.0714 ]
[ -0.1429 2.1429 -0.7857 ]
[ 0.0000 -1.0000 0.5000 ]
## 検算: ##
[ 1.0000 0.0000 0.0000 ]
[ 0.0000 1.0000 0.0000 ]
[ 0.0000 0.0000 1.0000 ]
= numpy.inv()に等しい
My det(): 14.0
numpy det(): 14.000000000000004
..LU分離検算..
XA: [[4. 1. 1.]
[1. 2. 3.]
[2. 4. 8.]]
A: [[4, 1, 1], [1, 2, 3], [2, 4, 8]]
P@L@U == A : OK
■◎◎ crout−2A ◎◎■
入力 A: [[0, 0, 3], [-1, 5, 2], [0, -1, 2]]
ランク(A): 3 , 3 x 3 行列
## My逆行列 ##
[ 4.0000 -1.0000 -5.0000 ]
[ 0.6667 -0.0000 -1.0000 ]
[ 0.3333 0.0000 0.0000 ]
## 検算: ##
[ 1.0000 0.0000 -0.0000 ]
[ 0.0000 1.0000 0.0000 ]
[ 0.0000 0.0000 1.0000 ]
= numpy.inv()に等しい
My det(): 3.0
numpy det(): 3.0000000000000004
..LU分離検算..
XA: [[ 0. 0. 3.]
[-1. 5. 2.]
[ 0. -1. 2.]]
A: [[0, 0, 3], [-1, 5, 2], [0, -1, 2]]
P@L@U == A : OK
■◎◎ crout−2B ◎◎■
入力 A: [[-1, 5, 2], [0, -1, 2], [0, 0, 3]]
ランク(A): 3 , 3 x 3 行列
## My逆行列 ##
[ -1.0000 -5.0000 4.0000 ]
[ -0.0000 -1.0000 0.6667 ]
[ 0.0000 0.0000 0.3333 ]
## 検算: ##
[ 1.0000 0.0000 -0.0000 ]
[ 0.0000 1.0000 -0.0000 ]
[ 0.0000 0.0000 1.0000 ]
= numpy.inv()に等しい
My det(): 3.0
numpy det(): 3.0000000000000004
..LU分離検算..
XA: [[-1. 5. 2.]
[ 0. -1. 2.]
[ 0. 0. 3.]]
A: [[-1, 5, 2], [0, -1, 2], [0, 0, 3]]
P@L@U == A : OK
■◎◎ crout−2C ◎◎■
入力 A: [[0, -1, 2], [0, 0, 3], [-1, 5, 2]]
ランク(A): 3 , 3 x 3 行列
## My逆行列 ##
[ -5.0000 4.0000 -1.0000 ]
[ -1.0000 0.6667 -0.0000 ]
[ 0.0000 0.3333 0.0000 ]
## 検算: ##
[ 1.0000 0.0000 -0.0000 ]
[ 0.0000 1.0000 -0.0000 ]
[ 0.0000 0.0000 1.0000 ]
= numpy.inv()に等しい
My det(): 3.0
numpy det(): 3.0000000000000004
..LU分離検算..
XA: [[ 0. -1. 2.]
[ 0. 0. 3.]
[-1. 5. 2.]]
A: [[0, -1, 2], [0, 0, 3], [-1, 5, 2]]
P@L@U == A : OK
■◎◎ crout−3 ◎◎■
入力 A: [[0, 1, 3, 0], [1, 0, 2, 4], [0, 0, 0, 1], [5, -4, -4, 0]]
ランク(A): 4 , 4 x 4 行列
## My逆行列 ##
[ 4.0000 -4.0000 16.0000 1.0000 ]
[ 7.0000 -7.5000 30.0000 1.5000 ]
[ -2.0000 2.5000 -10.0000 -0.5000 ]
[ 0.0000 0.0000 1.0000 0.0000 ]
## 検算: ##
[ 1.0000 0.0000 -0.0000 0.0000 ]
[ -0.0000 1.0000 -0.0000 0.0000 ]
[ 0.0000 0.0000 1.0000 0.0000 ]
[ 0.0000 0.0000 0.0000 1.0000 ]
= numpy.inv()に等しい
My det(): -1.9999999999999973
numpy det(): -1.9999999999999982
..LU分離検算..
XA: [[ 0. 1. 3. 0.]
[ 1. 0. 2. 4.]
[ 0. 0. 0. 1.]
[ 5. -4. -4. 0.]]
A: [[0, 1, 3, 0], [1, 0, 2, 4], [0, 0, 0, 1], [5, -4, -4, 0]]
P@L@U == A : OK
■◎◎ crout−4 ◎◎■
入力 A: [[0, 4, 1, 0], [1, 0, 2, 2], [0, 0, 0, 0], [0, 0, 0, 1]]
ランク(A): 3 , 4 x 4 行列
## My逆行列 ##
結果がありません
--- - - - - - - - -
プログラム:
---- crout-lu3.py -----
'''
(参照1) Numerical Recipes in C Second Edition
Chapter 2. Solution of Linear Algebraic Equations
ludcmp()
(参照2) https://stackoverflow.com/questions/5690010/lu-decomposition-from-numerical-recipes-not-working-what-am-i-doing-wrong
LU Decomposition from Numerical Recipes not working; what am I doing wrong?
'''
def ludcmp(PA, EPS=1.0e-7):
'''
LU分解
入力: A 行列
出力: LU 形式 | xUU |
| LxU |
| LLx |
INDEX
Sign 行列式符号
P 行の並び [0,1,2,3]
'''
n = len(PA)
m = len(PA[0])
if type(PA) != list or type(PA[0]) != list or n != m:
return None, None, None, None
A = [e.copy() for e in PA]
vv: list = [0] * n
index: list = [0] * n
P = [ _ for _ in range(n)]
imax = -1
d = 1.0
for i in range(n):
big = 0
for j in range(n):
temp = abs(A[i][j])
if temp > big:
big = temp
if big < EPS:
return None, None, None, None
vv[i] = 1.0 / big
for j in range(n): # crout method Loop
for i in range(j):
sum = A[i][j]
for k in range(i):
sum -= A[i][k] * A[k][j]
A[i][j] = sum
big = 0
for i in range(j,n):
sum = A[i][j]
for k in range(j):
sum -= A[i][k] * A[k][j]
A[i][j] = sum
dum = vv[i] * abs(sum)
if dum >= big:
big = dum
imax = i
if j != imax:
for k in range(n):
dum = A[imax][k]
A[imax][k] = A[j][k]
A[j][k] = dum
xs = P[imax]
P[imax] = P[j]
P[j] = xs
d = -d
vv[imax] = vv[j]
index[j] = imax
if j != (n-1):
dum = 1.0 / A[j][j]
for i in range(j+1,n):
A[i][j] *= dum
return A, index, d, P
def lubksb(A,index,Pb):
n = len(A)
b = [ e for e in Pb]
for i in range(n):
ip = index[i]
sum = b[ip]
b[ip] = b[i]
for j in range(i):
sum -= A[i][j] * b[j]
b[i] = sum
for i in range(n-1, -1, -1):
sum = b[i]
for j in range(i+1,n):
sum -= A[i][j] * b[j]
b[i] = sum / A[i][i]
return b
#--^^^
def lu_inverse(PA):
n = len(PA)
INV = [[0 for _ in range(n)] for _ in range(n)]
LU, P, _ , _ = ludcmp(PA)
if LU is None:
return None
for i in range(n):
b = [0.0 if k != i else 1 for k in range(n)]
x = lubksb(LU,P,b)
for ln in range(n):
INV[ln][i] = x[ln]
return INV
def get_low(A):
''' LOWmatrix
A is mixed LU ==>> |1,0,0|
|9,1,0|
|9,9,1|
'''
n = len(A)
low = [[0 if j != i else 1 for j in range(n)] for i in range(n)]
for i in range(n):
for j in range(n):
if j < i:
low[i][j] = A[i][j]
return low
def get_up(A):
''' UPmatrix
A is mixed LU ==>> |9,9,9|
|0,9,9|
|0,0,9|
'''
n = len(A)
up = [[0 if j != i else 1 for j in range(n)] for i in range(n)]
for i in range(n):
for j in range(n):
if j >= i:
up[i][j] = A[i][j]
return up
def get_liinf(P):
''' Pmatrix
P:[0,1,2,3] ==>> |1,0,0| 使い方: (Pmatrix @ LOWmatrix @ UPmatrix) == A matrix
|0,1,0|
|0,0,1|
'''
n = len(P)
Pm: list = [[] for _ in range(n)]
for i in range(n):
Pm[P[i]] = [0 if j != i else 1 for j in range(n)]
return Pm
def pmatrix(msg, MAT):
'''
行列の印刷
'''
print("##",msg,"##")
if MAT is None:
print(" 結果がありません")
return
n = len(MAT)
m = len(MAT[0])
for i in range(n):
print("[",end='')
for j in range(m):
print(" % .4f" % (MAT[i][j]), end='')
print(" ]")
if __name__ == "__main__":
import numpy as np
def p_header():
print("実行結果: LU,index,det-sign, ps, 行入れ替え = ludcmpt() - LU分解Mix")
print(" (参照1) Numerical Recipes in C Second Edition")
print(" Chapter 2. Solution of Linear Algebraic Equations")
print(" ludcmp() , lubksb()")
print(" (参照2) https://stackoverflow.com/questions/5690010/lu-decomposition-from-numerical-recipes-not-working-what-am-i-doing-wrong")
print(" LU Decomposition from Numerical Recipes not working; what am I doing wrong?")
print("....")
def ematrix(A):
la = np.linalg.matrix_rank(A)
print("ランク(A):",la, " , ",len(A) , "x",len(A[0])," 行列")
def test_inv(msg, A):
print('')
print("■◎◎",msg,"◎◎■")
print("入力 A:",A)
ematrix(A)
plu_inv = lu_inverse(A)
pmatrix( "My逆行列", plu_inv)
if plu_inv is not None:
pmatrix("検算:",np.dot(plu_inv,A))
ninv = np.linalg.inv(A)
if np.allclose(plu_inv, ninv):
print("= numpy.inv()に等しい")
else:
print("= numpy.inv()と違う??")
pmatrix("numpy:",ninv)
LU, _, ds, PP = ludcmp(A)
det = 1
for ti in range(len(A)):
det *= LU[ti][ti]
det *= ds
print("My det():", det)
print("numpy det():", np.linalg.det(A))
print("..LU分離検算..")
LU, _ , _ , PP = ludcmp(A)
PMT = get_liinf(PP)
XL= get_low(LU)
XU = get_up(LU)
XA = np.dot(np.dot(PMT,XL),XU)
print("XA:",XA)
print("A:",A)
if np.allclose(XA,np.array(A)):
print(" P@L@U == A : OK")
else:
print(" P@L@U == A : NG")
p_header()
test_inv("crout−1a",[[1,2,3],[2,4,8],[4,1,1]])
test_inv("crout−1b",[[2,4,8],[1,2,3],[4,1,1]])
test_inv("crout−1c",[[4,1,1],[1,2,3],[2,4,8]])
test_inv("crout−2A",[[0,0,3],[-1,5,2],[0,-1,2]])
test_inv("crout−2B",[[-1,5,2],[0,-1,2],[0,0,3]])
test_inv("crout−2C",[[0,-1,2],[0,0,3],[-1,5,2]])
test_inv("crout−3",[[0, 1, 3, 0], [1, 0, 2, 4], [0, 0, 0, 1], [5, -4, -4, 0]])
test_inv("crout−4",[[0, 4, 1, 0], [1, 0, 2, 2], [0, 0, 0, 0], [0, 0, 0, 1]])
2024-09-14 「行列計算 ガウスザイディル計算」
ガウスザイディル法で、反復法の行列計算をやってみた。
直接法で答のでるものが反復法では出ないものがある。
対角優位行列判定をすればよいとあったが、判定が否であっても反復法で収束する場合がある。
計算途中で収束しなかったらエラー扱いとした。
n
+--
> \
A[i][i] = / | A[i][j] | (j=1,2,...,n && j != i) THEN "対角優位"
+--
j=1
ELSE: "対角優位でない"
実行:
$ python GSeidel20.py
実行結果: 答,行入れ替え,ワーニング,計算回数 = gauss_seidel2() - GMRES法
参照:https://en.wikipedia.org/wiki/Gauss%E2%80%93Seidel_method
Gauss–Seidel method
http://nkl.cc.u-tokyo.ac.jp/15n/SolverIterative-25-29.pdf
SolverIterative-25-29.pdf
https://kishorkafle.medium.com/python-code-for-guass-seidel-method-fe948e4f46d2
Python Code for Guass-Seidel Method
数値計算 高橋大輔著 岩波 1996,2022
SORアルゴリズムより ω=1でガウスディザイル法
....
計算−1 ● ***Results***
A ---
[[8.0, 5.0, -3.0, 4.0], [4.0, 3.0, -1.0, 2.0], [2.0, 2.0, -1.0, 1.0], [3.0, 3.0, -2.0, 2.0]]
B ---
[12.0, 6.0, 4.0, 6.0]
**Answers**
行入れ替え情報: [0, 1, 2, 3]
答 --
1
1
-1
-1
..検算:
-8.4957e-07
-4.24588e-07
-2.12152e-07
0
..収束回数: 50
..警告: 1
計算−2 ● ***Results***
A ---
[[3, 2, 1], [1, 4, 1], [2, 2, 5]]
B ---
[10, 12, 21]
**Answers**
行入れ替え情報: [0, 1, 2]
答 --
1
2
3
..検算:
8.41962e-08
7.25989e-08
0
..収束回数: 13
..警告: 0
計算−3 ● ***Results***
A ---
[[0, -2, 0], [-1, 5, 2], [0, -1, 1]]
B ---
[1, 0, 0]
**Answers**
行入れ替え情報: [1, 0, 2]
答 --
-3.5
-0.5
-0.5
..検算:
0
0
0
..収束回数: 2
..警告: 3
計算−4 ● ***Results***
A ---
[[0, 0, 3], [-1, 5, 2], [0, -1, 2]]
B ---
[1, 0, 0]
**Answers**
行入れ替え情報: [1, 2, 0]
答 --
4
0.666667
0.333333
..検算:
0
-2.22045e-16
0
..収束回数: 3
..警告: 5
計算−5. ● ***Results***
A ---
[[2, -1, -1], [-1, 3, -1], [-1, -1, 1]]
B ---
[1, 0, 0]
**Answers**
行入れ替え情報: [0, 1, 2]
計算したが、収束しない
答 --
168996
134408
303403
..収束回数: 45
..警告: -1001
計算−6 ● ***Results***
A ---
[[0.0, 1.0], [1.0, 0.0]]
B ---
[1.0, 0.0]
**Answers**
行入れ替え情報: [1, 0]
答 --
0
1
..検算:
0
0
..収束回数: 1
..警告: 0
計算−7 ● ***Results***
A ---
[0.0]
B ---
0
**Answers**
計算できません
警告: 200
計算−8 ● ***Results***
A ---
[[4]]
B ---
[1]
**Answers**
行入れ替え情報: [0]
答 --
0.25
..検算:
0
..収束回数: 1
..警告: 0
oooooooooooooooooo
TEST MATRIX No. 1
30 x 30 行列
..検算:
OK
..収束回数: 12
..警告: 1
TEST MATRIX No. 2
34 x 34 行列
..検算:
OK
..収束回数: 8
..警告: 0
TEST MATRIX No. 3
21 x 21 行列
..検算:
OK
..収束回数: 8
..警告: 0
TEST MATRIX No. 4
23 x 23 行列
..検算:
OK
..収束回数: 8
..警告: 0
TEST MATRIX No. 5
10 x 10 行列
..検算:
OK
..収束回数: 33
..警告: 1
〜〜〜〜〜〜
プログラム:
---- GSeidel20.py ----
'''
参考:
https://en.wikipedia.org/wiki/Gauss%E2%80%93Seidel_method
Gauss–Seidel method
http://nkl.cc.u-tokyo.ac.jp/15n/SolverIterative-25-29.pdf
SolverIterative-25-29.pdf
https://kishorkafle.medium.com/python-code-for-guass-seidel-method-fe948e4f46d2
Python Code for Guass-Seidel Method
数値計算 高橋大輔著 岩波 1996,2022
SORアルゴリズムより ω=1でガウスディザイル法
'''
def check_d(A):
'''
対角優位行列判定 判定が否であっても反復法で収束する場合がある。注意事項の扱い。
計算途中で収束しなかったらエラー扱い。
n
+--
> \
A[i][i] = / | A[i][j] | (j=1,2,...,n && j != i) THEN return 0
+--
j=1
ELSE: return 1 # Worninng
'''
r = len(A)
ok = 0
for i in range(r):
non_diagnl = 0
for j in range(r):
non_diagnl += abs(A[i][j])
if abs(A[i][i]) < (non_diagnl-abs(A[i][i])):
ok = 1
return ok
def check_z(A, B):
'''
対角成分 ゼロチェック、ゼロならば行を入れ替える。対角成分にゼロがあると計算できない判定。
対角成分は1行目から、1回しか見ない。
A[i][i] == 0 THEN A[i] <=> A[x]; B[i] <=> B[x]; P[i] <=> P[x];
'''
r = len(A)
m = len(A[0])
P = [ _ for _ in range(r)]
A0 = [e.copy() for e in A]
B0 = [e for e in B]
for i in range(r):
if float(A0[i][i]) == 0.0:
for j in range(i+1,r):
if float(A0[j][i]) != 0.0:
for x in range(m):
xs = A0[i][x]
A0[i][x] = A0[j][x]
A0[j][x] = xs
xp = P[i]
P[i] = P[j]
P[j] = xp
xs = B0[i]
B0[i] = B0[j]
B0[j] = xs
break
else:
return None,None, None
return A0, B0, P
def allclose(a,b,E=1e-8):
'''
ベクトル比較
'''
n = len(a)
for i in range(n):
if abs(a[i]-b[i]) >= E:
return False
return True
def gauss_seidel(A, B, EPS=1.0e-7, iterMax=100):
'''
GAUSS-SEIDEL Method
'''
n = len(A)
if type(A[0]) != list:
m = 1
else:
m = len(A[0])
#initial value
X = [0.0 for _ in range(n)]
difference = [1.0 for _ in range(n)]
error = 0.0
A1 , B1, P = check_z(A,B)
if A1 is None:
return None, None, 200, 0
#
# n
# +--
# > \
# A[i][i] = / | A[i][j] | (j=1,2,...,n && j != i) THEN chkf = 0
# +--
# j=1
# ELSE: chkf = 1 # Worning
# ( 行入れ替えた後 )
chkf = check_d(A1)
if n == 1:
if abs(A1[0][0]) < EPS:
return None, None, 200, 1
else:
X[0] = B1[0] / A1[0][0]
return X, [0], 0, 1
ec = 0
for iter in range(iterMax+1):
x_new = [0.0 for _ in range(n)]
for i in range(n):
s1 = 0.0
s2 = 0.0
for j in range(i):
s1 += A1[i][j] * x_new[j]
for j in range(i+1,n):
s2 += A1[i][j] * X[j]
x_new[i] = (B1[i] - s1 - s2) / A1[i][i]
if allclose(x_new, X, E=EPS):
break
if (abs(x_new[0]) - abs(X[0])) > 0:
ec += 1
if ec > iterMax:
return X, P, -((chkf & 1)+1000), iter
X = x_new
else:
return None, P, chkf, iter
'''
X : 答
P : 行の入れ替え順列
chkf : 「(chkf & 1) == 1」 対角優位行列でない, 「(chkf & 0xFFFE) == 999」 答が大きくなり続けることがあった
「 chkf == -1000 or -1001」 答が計算できないことになった
iter : 計算繰り返し数
'''
return X, P, chkf, iter
def gauss_seidel2(A, B, EPS=1.0e-7, iterMax=100):
'''
GAUSS-SEIDEL Method
'''
n = len(A)
if type(A[0]) != list:
m = 1
else:
m = len(A[0])
#initial value
X = [0.0 for _ in range(n)]
difference = [1.0 for _ in range(n)]
error = 0.0
A1 , B1, P = check_z(A,B)
if A1 is None:
return None, None, 200, 0
#
# n
# +--
# > \
# A[i][i] = / | A[i][j] | (j=1,2,...,n && j != i) THEN chkf = 0
# +--
# j=1
# ELSE: chkf = 1 # Worning
# ( 行入れ替えた後 )
chkf = check_d(A1)
if n == 1:
if abs(A1[0][0]) < EPS:
return None, None, 200, 1
else:
X[0] = B1[0] / A1[0][0]
return X, [0], 0, 1
'''
数値計算 高橋大輔著 岩波 1996,2022
SORアルゴリズムより ω=1でガウスディザイル法
'''
cks = -1
for iter in range(iterMax+1):
error = 0
sum = 0
for i in range(n):
sums = 0
for j in range(m):
if (i != j):
sums += A1[i][j] * X[j]
new_ = (B1[i] - sums) / A1[i][i]
sum += abs(new_)
error += abs(new_ - X[i])
X[i] = new_
if error <= (EPS * sum):
break
if cks >= 0:
if cks < error:
chkf += 2
if chkf > (iterMax-10):
return X, P, -((chkf & 1)+1000), iter
cks = error
else:
return None, P, chkf, iter
'''
X : 答
P : 行の入れ替え順列
chkf : 「(chkf & 1) == 1」 対角優位行列でない, 「(chkf & 0xFFFE) == 999」 答が大きくなり続けることがあった
「 chkf == -1000 or -1001」 答が計算できないことになった
iter : 計算繰り返し数
'''
return X, P, chkf, iter
def chk(a,b):
if type(a) == list:
if len(a) == 0:
return None
else:
if type(a[0]) != list:
A = [a.copy()]
else:
A = [e.copy() for e in a]
n = len(A)
m = len(A[0])
else:
n = 0
m = 0
if m != n or n == 0: # 正方行列のみ
return None, None
if type(b) == list:
if len(b) == 0:
return None, None
if type(b[0]) == list:
return None, None
else:
b = [b]
nb = len(b)
if nb != n or nb == 0:
return None, None
return A,b
if __name__ == '__main__':
import numpy as np
def p_header():
print("実行結果: 答,行入れ替え,ワーニング,計算回数 = gauss_seidel2() - GMRES法")
print(" 参照:https://en.wikipedia.org/wiki/Gauss%E2%80%93Seidel_method")
print(" Gauss–Seidel method")
print(" http://nkl.cc.u-tokyo.ac.jp/15n/SolverIterative-25-29.pdf")
print(" SolverIterative-25-29.pdf")
print(" https://kishorkafle.medium.com/python-code-for-guass-seidel-method-fe948e4f46d2")
print(" Python Code for Guass-Seidel Method")
print(" 数値計算 高橋大輔著 岩波 1996,2022")
print(" SORアルゴリズムより ω=1でガウスディザイル法")
print("....")
def gen_matrix(n=0, RMAX=50, DCP=1):
'''
行列生成 N x N
n = 0 : ランダムNxN , 9 : 9 x 9行列
RMAX = 50 : (+-50)で要素データ、 99: (+-99)で要素データ
DCP = 1 : 要素データ * 10, +9 : 要素データ * (10**9) 、 -9 : 要素データ / (10**9)
'''
import random as r
DC = 10**abs(DCP)
if n == 0:
N = r.randrange(10,41) # 10x10 ~ 40x40の行列を作る
else:
N = n # n x n の行列を作る
nx = r.randrange(N*4) # 時々、対角優位行列でなくする
m = []
for i in range(N):
m.append([r.randrange(-RMAX,RMAX+1) for j in range(N)])
for i in range(N):
if i != nx:
ml = 0
for j in range(N):
if i != j:
ml += abs(m[i][j])
if m[i][i] < 0:
m[i][i] -= ml
else:
m[i][i] += ml
for i in range(N):
for j in range(N):
if DCP < 0:
m[i][j] /= DC
else:
m[i][j] *= DC
b = [0 if (j & 11) == 0 else r.randrange(-RMAX,RMAX+1) for j in range(N)]
for i in range(N):
if DCP < 0:
b[i] /= DC
else:
b[i] *= DC
return m,b
def print_ans(a):
print("答 --")
for i in a:
print(" %.6g" % (i))
def testMatrix(nc):
for n in range(1, nc+1):
print("")
print("TEST MATRIX No.", n)
A, b = gen_matrix(RMAX=360, DCP=-2)
nn = len(A)
print(" %d x %d 行列" % (nn,nn))
ret = gauss_seidel2(A,b)
#ret = gauss_seidel(A, b)
if ret[0] is None: # 収束できない、左辺行列がない、左辺行列式が零
print(" 計算できません")
print(" 収束回数:", ret[3])
print(" 警告:", ret[2])
else:
if ret[2] < 0: # 計算しないとわからない収束しない左辺行列
print(" 計算したが、収束しない")
for i in ret[0]:
print(" %.6g" % (i))
else:
print("..検算:")
Bb = np.array([ret[0]]).T
diff = np.dot(A,Bb)
dif = [b] - diff.T
for i in dif[0]:
if i >= 0.0001:
print(" NG??", i)
print("A ---N:", len(A))
print(A)
print("B ---")
print(b)
print_ans(ret[0])
break
else:
print(" OK")
print("..収束回数:", ret[3])
print("..警告:", ret[2])
def test(msg,mat, mb):
print("\n",msg," ● ***Results***")
print("A ---")
print(mat)
print("B ---")
print(mb)
print("**Answers**")
A, b = chk(mat,mb)
if A is None: # 左辺行列がない
print("計算できません")
return
ret = gauss_seidel2(A, b)
#ret = gauss_seidel(A, b)
if ret[0] is None: # 収束できない、左辺行列式が零
print(" 計算できません")
print(" 警告:", ret[2])
else:
print("行入れ替え情報:", ret[1])
if ret[2] < 0: # 計算しないとわからない収束しない左辺行列
print(" 計算したが、収束しない")
print_ans(ret[0])
else:
print_ans(ret[0])
Bb = np.array([ret[0]]).T
diff = np.dot(A,Bb)
print("..検算:")
dif = [b] - diff.T
for i in dif[0]:
print(" %.6g" % (i))
print("..収束回数:", ret[3])
print("..警告:", ret[2])
p_header()
test("計算−1", [[8.0,5.0,-3.0,4.0],[4.0,3.0,-1.0,2.0],[2.0,2.0,-1.0,1.0],[3.0,3.0,-2.0,2.0]],[12.0,6.0,4.0,6.0]) # original
test("計算−2",[[3,2,1],[1,4,1],[2,2,5]],[10,12,21])
test("計算−3",[[0,-2,0],[-1,5,2],[0,-1,1]],[1,0,0])
test("計算−4",[[0,0,3],[-1,5,2],[0,-1,2]],[1,0,0])
test("計算−5.",[[2,-1,-1],[-1,3,-1],[-1,-1,1]],[1,0,0])
test("計算−6",[ [0.0, 1.0],[1.0, 0.0] ], [1.,0.])
test("計算−7",[0.0], 0)
test("計算−8",[[4]],[1])
print("\noooooooooooooooooo",end='')
testMatrix(5)
---
2024-09-14 「逆行列計算2.1」
反復法 GMRES法で、逆行列計算をやってみた。
行列の内容によっては解法結果がでない場合がある。
いろいろやったみたら、行の絶対値の小さい順に行を並び替えたらできるようである。
やってみたらのことなのでそのつもりで見てください。
参考:
https://tech-commonplace.com/gmres_method/
C言語によるGMRES法の実装
https://medium.com/@giorgio.martinez1926/understanding-gmres-using-python-3c314fac1264
Understanding GMRES using python
https://stackoverflow.com/questions/52951533/following-code-i-have-made-an-sor-iteration-in-python
following code I have made an SOR iteration in python
「C言語によるGMRES法の実装」より、C言語のプログラムをPYTHONに変換した。ありがとうございます。
ちょっと修正しました。
実行:
$ python cgmres.py
実行結果: 答 = gmres() - GMRES法
参照:https://tech-commonplace.com/gmres_method/
C言語によるGMRES法の実装
https://medium.com/@giorgio.martinez1926/understanding-gmres-using-python-3c314fac1264
Understanding GMRES using python
....
--- 逆行列計算 --- テスト1
A: [[2.0, 3.0, 1.0, -3.0], [-1.0, 2.0, 2.0, 4.0], [4.0, 1.0, -3.0, 5.0], [5.0, -4.0, -4.0, 1.0]]
ランク(A): 4 4 x 4 行列
--scipy.sparse.linalg.gmres 逆行列--
[[ 0.21052632 0.22807018 -0.10526316 0.24561404]
[ 0.06140351 -0.16959064 0.21929825 -0.23391813]
[ 0.18421053 0.49122807 -0.34210526 0.29824561]
[-0.07017544 0.14619883 0.03508772 0.02923977]]
--My gmres 逆行列--
[[ 0.21052632 0.22807018 -0.10526316 0.24561404]
[ 0.06140351 -0.16959064 0.21929825 -0.23391813]
[ 0.18421053 0.49122807 -0.34210526 0.29824561]
[-0.07017544 0.14619883 0.03508772 0.02923977]]
scipy gmres() inv: OK
--- 逆行列計算 --- テスト2
A: [[2, 3], [4, 2]]
ランク(A): 2 2 x 2 行列
--scipy.sparse.linalg.gmres 逆行列--
[[-0.25 0.375]
[ 0.5 -0.25 ]]
--My gmres 逆行列--
[[-0.25 0.375]
[ 0.5 -0.25 ]]
scipy gmres() inv: OK
--- 逆行列計算 --- テスト3
A: [[1, 2, 3], [2, 4, 8], [4, 1, 1]]
ランク(A): 3 3 x 3 行列
--scipy.sparse.linalg.gmres 逆行列--
[[-2.85714286e-01 7.14285714e-02 2.85714286e-01]
[ 2.14285714e+00 -7.85714286e-01 -1.42857143e-01]
[-1.00000000e+00 5.00000000e-01 -6.83650965e-17]]
--My gmres 逆行列--
[[-2.85714286e-01 7.14285714e-02 2.85714286e-01]
[ 2.14285714e+00 -7.85714286e-01 -1.42857143e-01]
[-1.00000000e+00 5.00000000e-01 -4.00401163e-16]]
scipy gmres() inv: OK
--- 逆行列計算 --- テストB-1.2.3
A: [[0, 0, 3], [1, 5, 2], [0, 1, 0]]
ランク(A): 3 3 x 3 行列
--scipy.sparse.linalg.gmres 逆行列--
[[-6.66666667e-01 1.00000000e+00 -5.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]
[ 3.33333333e-01 0.00000000e+00 3.19211673e-16]]
--My gmres 逆行列--
[[-6.66666667e-01 1.00000000e+00 -5.00000000e+00]
[ 1.22124533e-15 -3.89088944e-16 1.00000000e+00]
[ 3.33333333e-01 -2.22044605e-16 1.08815408e-15]]
scipy gmres() inv: OK
--- 逆行列計算 --- テストB-1,3,2
A: [[0, 0, 3], [0, 1, 0], [1, 5, 2]]
ランク(A): 3 3 x 3 行列
--scipy.sparse.linalg.gmres 逆行列--
[[-6.66666667e-01 -5.00000000e+00 1.00000000e+00]
[ 0.00000000e+00 1.00000000e+00 0.00000000e+00]
[ 3.33333333e-01 -7.46368420e-18 0.00000000e+00]]
--My gmres 逆行列--
[[-6.66666667e-01 -5.00000000e+00 1.00000000e+00]
[ 1.22124533e-15 1.00000000e+00 -3.89088944e-16]
[ 3.33333333e-01 1.08815408e-15 -2.22044605e-16]]
scipy gmres() inv: OK
--- 逆行列計算 --- テストB-2,1,3
A: [[1, 5, 2], [0, 0, 3], [0, 1, 0]]
ランク(A): 3 3 x 3 行列
--scipy.sparse.linalg.gmres 逆行列--
[[ 1.00000000e+00 -6.66666667e-01 -5.00000000e+00]
[ 0.00000000e+00 -1.46331040e-17 1.00000000e+00]
[ 0.00000000e+00 3.33333333e-01 7.29780195e-17]]
--My gmres 逆行列--
[[ 1.00000000e+00 -6.66666667e-01 -5.00000000e+00]
[-3.89088944e-16 1.22124533e-15 1.00000000e+00]
[-2.22044605e-16 3.33333333e-01 1.08815408e-15]]
scipy gmres() inv: OK
--- 逆行列計算 --- テストB-2,3,1
A: [[1, 5, 2], [0, 1, 0], [0, 0, 3]]
ランク(A): 3 3 x 3 行列
--scipy.sparse.linalg.gmres 逆行列--
[[ 1. -5. -0.66666667]
[ 0. 1. 0. ]
[ 0. 0. 0.33333333]]
--My gmres 逆行列--
[[ 1.00000000e+00 -5.00000000e+00 -6.66666667e-01]
[-3.89088944e-16 1.00000000e+00 1.22124533e-15]
[-2.22044605e-16 1.08815408e-15 3.33333333e-01]]
scipy gmres() inv: OK
--- 逆行列計算 --- テストB-3,1,2
A: [[0, 1, 0], [0, 0, 3], [1, 5, 2]]
ランク(A): 3 3 x 3 行列
--scipy.sparse.linalg.gmres 逆行列--
[[-5.00000000e+00 -6.66666667e-01 1.00000000e+00]
[ 1.00000000e+00 1.37599254e-17 0.00000000e+00]
[ 0.00000000e+00 3.33333333e-01 0.00000000e+00]]
--My gmres 逆行列--
[[-5.00000000e+00 -6.66666667e-01 1.00000000e+00]
[ 1.00000000e+00 1.22124533e-15 -3.89088944e-16]
[ 1.08815408e-15 3.33333333e-01 -2.22044605e-16]]
scipy gmres() inv: OK
--- 逆行列計算 --- テストB-3,2,1
A: [[0, 1, 0], [1, 5, 2], [0, 0, 3]]
ランク(A): 3 3 x 3 行列
--scipy.sparse.linalg.gmres 逆行列--
[[-5.00000000e+00 1.00000000e+00 -6.66666667e-01]
[ 1.00000000e+00 0.00000000e+00 1.39944079e-17]
[ 0.00000000e+00 0.00000000e+00 3.33333333e-01]]
--My gmres 逆行列--
[[-5.00000000e+00 1.00000000e+00 -6.66666667e-01]
[ 1.00000000e+00 -3.89088944e-16 1.22124533e-15]
[ 1.08815408e-15 -2.22044605e-16 3.33333333e-01]]
scipy gmres() inv: OK
... 方程式解法計算 ...
A: [[], []]
b: []
計算できません
... 方程式解法計算 ...
A: [0.0]
b: 0
ランク(A): 0 1 x 1 行列
方程式計算できません
... 方程式解法計算 ...
A: [[1, 2], [3, 4]]
b: [0, 1]
ランク(A): 2 2 x 2 行列
x =
1.000000, -0.500000,
--scipy.sparse.linalg.gmres 答:
1.000000, -0.500000,
... 方程式解法計算 ...
A: [[1.0, 3.0, 9.0], [-1.0, 1.0, -1.0], [2.0, -4.0, -2.0]]
b: [1, 0, 0]
ランク(A): 2 3 x 3 行列
方程式計算できません
...
プログラム:
---- cgmres.py ----
'''
参考:
https://tech-commonplace.com/gmres_method/
C言語によるGMRES法の実装
https://medium.com/@giorgio.martinez1926/understanding-gmres-using-python-3c314fac1264
Understanding GMRES using python
'''
import math
# 転置行列
def transpose(row, col, mat, mat_T):
for i in range(row):
for j in range(col):
mat_T[j][i] = mat[i][j]
# k * vec = ans
def vec_multi(n, vec, k, ans):
for i in range(n):
ans[i] = vec[i] * k
# vec / k = ans
def vec_div(n,vec,k, ans):
for i in range(n):
ans[i] = vec[i] / k
# mat*vec = ans
def mat_multi_vec(row, col, mat, vec, ans):
for i in range(row):
ans[i] = 0.0
for j in range(col):
ans[i] += mat[i][j] * vec[j]
# vec1 + vec2 = ans
def vec_add_vec(n, vec1, vec2, ans):
for i in range(n):
ans[i] = vec1[i] + vec2[i]
# vec1 - vec2 = ans
def vec_sub_vec(n, vec1, vec2, ans):
for i in range(n):
ans[i] = vec1[i] - vec2[i]
# 代入
def vec_subs_vec(n, vec, ans):
for i in range(n):
ans[i] = vec[i]
# 内積
def dot(n, vec1, vec2):
ans = 0.0;
for i in range(n):
ans += vec1[i] * vec2[i]
return ans
# 0 ベクトルの生成
def zero_vec(n, vec):
for i in range(n):
vec[i] = 0.0
# ベクトルをprint
def print_vec(n, vec):
for i in range(n):
print("%4.6f, " % (vec[i]), end='')
print("")
# 行列を print
def print_mat(row, col, mat):
for i in range(row):
for j in range(col):
print("%4.6f, " % (mat[i][j]),end='')
print("")
def gmres(A, b, k=10, EPS=1.0e-20):
'''
gmres 法を用いて A*x = b の解を求める
入力: 左辺行列A N x N
右辺行列b 1 x N
作業域の大きさk
マシンイプシロンEPS
出力: 答ans 1 x N / エラー None
'''
row = len(A)
col = len(A[0])
ans = [0.0 for _ in range(row)]
if row == 1:
if abs(A[0][0]) < EPS:
return None
else:
ans[0] = b[0] / A[0][0]
return ans
mx = max(row,col)
if mx < k or (k - mx) < 5:
m = max(row,col) + 10
else:
m = k
# メモリ割当
Avj = [0.0 for _ in range(row)]
r0 = [0.0 for _ in range(row)]
g = [0.0 for _ in range(m+1)]
c = [0.0 for _ in range(m)]
s = [0.0 for _ in range(m)]
y = [0.0 for _ in range(m)]
x0 = [d for d in b]
delta_x = [0.0 for _ in range(row)]
tmpvec = [0.0 for _ in range(row)]
# 行列はすべて転置して定義
Vm = [[0.0 for _ in range(row)] for _ in range(m+1)]
Vm_T = [[0.0 for _ in range(m+1)] for _ in range(row)]
Hm = [[0.0 for _ in range(m+1)] for _ in range(m+1)]
Rm = [[0.0 for _ in range(m+1)] for _ in range(m)]
mat_multi_vec(row, col, A, x0, Avj)
vec_sub_vec(row,b,Avj,r0)
r0_norm = math.sqrt(dot(row,r0,r0))
if type(r0_norm) is complex or abs(r0_norm) < EPS:
#if type(Hm[j][j+1]) is complex:
return None
vec_div(row,r0,r0_norm,Vm[0])
g[0] = r0_norm
for j in range(m):
# Arnoldi 法
mat_multi_vec(row,col,A,Vm[j],Avj)
zero_vec(row, tmpvec)
for i in range(j+1):
Hm[j][i] = dot(row, Avj, Vm[i])
vec_multi(row,Vm[i],Hm[j][i],Vm[j+1])
vec_add_vec(row,tmpvec,Vm[j+1],tmpvec)
vec_sub_vec(row, Avj, tmpvec, Vm[j+1])
Hm[j][j+1] = math.sqrt(dot(row, Vm[j+1], Vm[j+1]))
if type(Hm[j][j+1]) is complex or abs(Hm[j][j+1]) < EPS:
return None
vec_div(row, Vm[j+1],Hm[j][j+1],Vm[j+1])
Rm[j][0] = Hm[j][0]
# Givens 回転
for i in range(j):
tmp1 = c[i]*Rm[j][i] - s[i]*Hm[j][i+1]
tmp2 = s[i]*Rm[j][i] + c[i]*Hm[j][i+1]
Rm[j][i] = tmp1
Rm[j][i+1] = tmp2
deno = math.sqrt(Rm[j][j]*Rm[j][j] + Hm[j][j+1]*Hm[j][j+1])
if type(deno) is complex or abs(deno) < EPS:
return None
c[j] = Rm[j][j] / deno
s[j] = -Hm[j][j+1] / deno
g[j+1] = s[j] * g[j]
g[j] = c[j] * g[j]
Rm[j][j] = c[j]*Rm[j][j] - s[j]*Hm[j][j+1]
# 後退代入
y[m-1] = g[m-1] / Rm[m-1][m-1]
for i in range(m-2, -1, -1):
tmp1 = 0.0
for j in range(i, m-1):
tmp1 += Rm[j][i]*y[j]
if abs(Rm[i][i]) < EPS:
break
y[i] = (g[i] - tmp1) / Rm[i][i]
else:
transpose(m+1,row,Vm,Vm_T)
mat_multi_vec(row,m,Vm_T,y,delta_x)
vec_add_vec(row,x0,delta_x,ans)
return ans
return None
def check_l(A, B):
'''
行の入れ替え 要素の絶対値が小さい順に並べ替え
'''
r = len(A)
m = len(A[0])
P = [ _ for _ in range(r)]
A0 = [e.copy() for e in A]
B0 = [e for e in B]
for k in range(r):
ae = abs(A0[k][0])
for j in range(1,r):
if abs(A0[k][j]) > ae:
ae = abs(A0[k][j])
mi = k
if k != (r-1):
k1 = k + 1
le = ae
for i in range(k1,r):
be = abs(A0[i][0])
for j in range(1,r):
if abs(A0[i][j]) > be:
be = abs(A0[i][j])
if le > be:
le = be
mi = i
if mi != k:
for j in range(m):
ss = A0[k][j]
A0[k][j] = A0[mi][j]
A0[mi][j] = ss
tt = P[k]
P[k] = P[mi]
P[mi] = tt
tt = B0[k]
B0[k] = B0[mi]
B0[mi] = tt
return A0, B0, P
def chk(a,b):
"""
指定行列を2次元に、式右辺をリストに変換
"""
if type(a) == list:
if len(a) == 0:
return None
else:
if type(a[0]) != list:
A = [a.copy()]
else:
A = [e.copy() for e in a]
n = len(A)
m = len(A[0])
else:
n = 0
m = 0
if m != n or n == 0: # 正方行列のみ
return None, None
if type(b) == list:
if len(b) == 0:
return None, None
if type(b[0]) == list:
return None, None
else:
b = [b]
nb = len(b)
if nb != n or nb == 0:
return None, None
return A,b
if __name__ == '__main__':
import numpy as np
from scipy.sparse.linalg import gmres as sci_gmres
def p_header():
print("実行結果: 答 = gmres() - GMRES法")
print(" 参照:https://tech-commonplace.com/gmres_method/")
print(" C言語によるGMRES法の実装")
print(" https://medium.com/@giorgio.martinez1926/understanding-gmres-using-python-3c314fac1264")
print(" Understanding GMRES using python")
print("....")
def test_inv(msg,Am):
print("--- 逆行列計算 ---", msg)
print("A:",Am)
ma, b = chk(Am,Am[0])
if ma is None:
print("計算できません")
return
N = len(ma)
lab = np.linalg.matrix_rank(np.array(ma))
print("ランク(A):",lab, " ",N,"x",N,"行列")
if lab != N:
print("逆行列計算できません")
return
INV = []
for i in range(N):
b = np.array([0.0] * N)
b[i] = 1.0
x, _ = sci_gmres(np.array(ma), b)
INV.append(x.tolist())
print("--scipy.sparse.linalg.gmres 逆行列--")
sciinv = np.array(INV).T
print(sciinv)
INV = []
for i in range(N):
b = [0.0 for _ in range(N)]
b[i] = 1.0
m1, mb , _ = check_l(ma,b)
ans = gmres(m1,mb)
if ans is None:
print("計算できませんでした")
return
else:
INV.append(ans)
print("--My gmres 逆行列--")
myinv = np.array(INV).T
print(myinv)
if np.allclose(myinv, sciinv):
print(" scipy gmres() inv: OK")
else:
print(" scipy gmres() inv: NG??")
print("")
def test(Am,v0):
print("... 方程式解法計算 ...")
print("A:",Am)
print("b:",v0)
A, b = chk(Am,v0)
if A is None:
print("計算できません")
else:
N = len(A)
lab = np.linalg.matrix_rank(A)
print("ランク(A):",lab, " ",N,"x",N,"行列")
if lab != N:
print("方程式計算できません")
else:
ans = gmres(A,b)
if ans is None:
print("計算できませんでした")
else:
print("x = ")
print_vec(N,ans)
x, _ = sci_gmres(np.array(A), b)
print("--scipy.sparse.linalg.gmres 答:")
print_vec(N,x)
print("")
p_header()
test_inv("テスト1",[[2.0, 3.0, 1.0, -3.0],[-1.0, 2.0, 2.0, 4.0],[4.0, 1.0, -3.0, 5.0],[5.0, -4.0, -4.0, 1.0]])
test_inv("テスト2",[[2,3],[4,2]])
test_inv("テスト3",[[1, 2, 3], [2, 4, 8], [4, 1, 1]])
test_inv("テストB-1.2.3",[[0,0,3],[1,5,2],[0,1,0]]) # 1,2,3
test_inv("テストB-1,3,2",[[0,0,3],[0,1,0],[1,5,2]]) # 1,3,2
test_inv("テストB-2,1,3",[[1,5,2],[0,0,3],[0,1,0]]) # 2,1,3
test_inv("テストB-2,3,1",[[1,5,2],[0,1,0],[0,0,3]]) # 2,3,1
test_inv("テストB-3,1,2",[[0,1,0],[0,0,3],[1,5,2]]) # 3,1,2
test_inv("テストB-3,2,1",[[0,1,0],[1,5,2],[0,0,3]]) # 3,2,1
test([[],[]], [])
test([0.0], 0)
test([[1,2],[3,4]], [0,1])
test([[1.0, 3.0, 9.0],[-1.0, 1.0, -1.0],[2.0, -4.0, -2.0]], [1,0,0])
...
2024-08-21 「行列・方程式解法ー逆行列 その他手順2題」
消去法の手順 その他2題
方程式解法とランク
行列 A : 係数行列
行列 B : 拡大行列(係数行列と右辺)
ランクA == ランクB == 係数行列行数 ・で・ 解ひとつ
ランクA == ランクB < 係数行列行数 ・で・ 解無限
ランクA < ランクB ・で・ 解なし
実行:
$ python another_elim.py
*************
*** TEST1 ***
*************
◆◆◆◆ gj1数値例(0) ◆◆◆◆
入力: MATRIX:
[ ]
計算できません
◆◆◆◆ gj1数値例(1) ◆◆◆◆
入力: MATRIX:
[ 2.00000 | 3.00000 ]
rank{A}: 1
rank{B}: 1
答は一つ : ランク(A) == ランク(AB) == A行数
方程式の解法結果: MATRIX:
[ 1.50000 ]
行入れ替え: [0]
◆◆◆◆ gj1数値例(2) ◆◆◆◆
入力: MATRIX:
[ 1.00000 0.99000 | 1.99000 ]
[ 0.99000 0.98000 | 1.97000 ]
rank{A}: 2
rank{B}: 2
答は一つ : ランク(A) == ランク(AB) == A行数
方程式の解法結果: MATRIX:
[ 1.00000 ]
[ 1.00000 ]
行入れ替え: [0, 1]
◆◆◆◆ gj1数値例(3) ◆◆◆◆
入力: MATRIX:
[ 2.00000 3.00000 1.00000 -3.00000 | 1.00000 ]
[ -1.00000 2.00000 2.00000 4.00000 | 6.00000 ]
[ 4.00000 1.00000 -3.00000 5.00000 | 3.00000 ]
[ 5.00000 -4.00000 -4.00000 1.00000 | 3.00000 ]
rank{A}: 4
rank{B}: 4
答は一つ : ランク(A) == ランク(AB) == A行数
方程式の解法結果: MATRIX:
[ 2.00000 ]
[ -1.00000 ]
[ 3.00000 ]
[ 1.00000 ]
行入れ替え: [0, 1, 2, 3]
◆◆◆◆ gj1 Rank(A) == Rank(A,b合わせた行列) < 4 ◆◆◆◆
入力: MATRIX:
[ 1.00000 3.00000 1.00000 -2.00000 | -3.00000 ]
[ 1.00000 4.00000 3.00000 -1.00000 | -4.00000 ]
[ 2.00000 3.00000 -4.00000 -7.00000 | -3.00000 ]
[ 3.00000 8.00000 1.00000 -7.00000 | -8.00000 ]
rank{A}: 2
rank{B}: 2
答は無限 : ランク(A) == ランク(AB) < A行数
計算できません
◆◆◆◆ gj1逆行列計算1 ◆◆◆◆
入力: MATRIX:
[ 2.00000 | 1.00000 ]
rank{A}: 1
rank{B}: 1
答は一つ : ランク(A) == ランク(AB) == A行数
方程式の解法結果: MATRIX:
[ 0.50000 ]
行入れ替え: [0]
..逆行列検算..
numpy.inv() と同じ
◆◆◆◆ gj1逆行列計算2 ◆◆◆◆
入力: MATRIX:
[ -1.00000 1.00000 1.00000 | 1.00000 0.00000 0.00000 ]
[ 1.00000 -1.00000 1.00000 | 0.00000 1.00000 0.00000 ]
[ 1.00000 1.00000 -1.00000 | 0.00000 0.00000 1.00000 ]
rank{A}: 3
rank{B}: 3
答は一つ : ランク(A) == ランク(AB) == A行数
方程式の解法結果: MATRIX:
[ 0.00000 0.50000 0.50000 ]
[ 0.50000 0.00000 0.50000 ]
[ 0.50000 0.50000 0.00000 ]
行入れ替え: [0, 2, 1]
..逆行列検算..
numpy.inv() と同じ
◆◆◆◆ gj1逆行列計算3 ◆◆◆◆
入力: MATRIX:
[ 0.00000 -2.00000 0.00000 | 1.00000 0.00000 0.00000 ]
[ -1.00000 5.00000 2.00000 | 0.00000 1.00000 0.00000 ]
[ 0.00000 -1.00000 1.00000 | 0.00000 0.00000 1.00000 ]
rank{A}: 3
rank{B}: 3
答は一つ : ランク(A) == ランク(AB) == A行数
方程式の解法結果: MATRIX:
[ -3.50000 -1.00000 2.00000 ]
[ -0.50000 0.00000 0.00000 ]
[ -0.50000 0.00000 1.00000 ]
行入れ替え: [1, 0, 2]
..逆行列検算..
numpy.inv() と同じ
◆◆◆◆ gj1逆行列計算4 ◆◆◆◆
入力: MATRIX:
[ 1.00000 3.00000 9.00000 | 1.00000 0.00000 0.00000 ]
[ -1.00000 1.00000 -1.00000 | 0.00000 1.00000 0.00000 ]
[ 2.00000 -4.00000 -2.00000 | 0.00000 0.00000 1.00000 ]
rank{A}: 2
rank{B}: 3
答はなし : ランク(A) < ランク(AB)
計算できません
*************
*** TEST2 ***
*************
◆◆◆◆ 消去法・数値例(0) ◆◆◆◆
入力: MATRIX:
[ ]
計算できません
◆◆◆◆ 消去法・数値例(1) ◆◆◆◆
入力: MATRIX:
[ 2.00000 | 3.00000 ]
rank{A}: 1
rank{B}: 1
答は一つ : ランク(A) == ランク(AB) == A行数
方程式の解法結果: MATRIX:
[ 1.50000 ]
行入れ替え: [0]
◆◆◆◆ 消去法・数値例(2) ◆◆◆◆
入力: MATRIX:
[ 1.00000 0.99000 | 1.99000 ]
[ 0.99000 0.98000 | 1.97000 ]
rank{A}: 2
rank{B}: 2
答は一つ : ランク(A) == ランク(AB) == A行数
方程式の解法結果: MATRIX:
[ 1.00000 ]
[ 1.00000 ]
行入れ替え: [0, 1]
◆◆◆◆ 消去法・数値例(3) ◆◆◆◆
入力: MATRIX:
[ 2.00000 3.00000 1.00000 -3.00000 | 1.00000 ]
[ -1.00000 2.00000 2.00000 4.00000 | 6.00000 ]
[ 4.00000 1.00000 -3.00000 5.00000 | 3.00000 ]
[ 5.00000 -4.00000 -4.00000 1.00000 | 3.00000 ]
rank{A}: 4
rank{B}: 4
答は一つ : ランク(A) == ランク(AB) == A行数
方程式の解法結果: MATRIX:
[ 2.00000 ]
[ -1.00000 ]
[ 3.00000 ]
[ 1.00000 ]
行入れ替え: [3, 0, 2, 1]
◆◆◆◆ 消去法・ Rank(A) == Rank(A,b合わせた行列) < 4 ◆◆◆◆
入力: MATRIX:
[ 1.00000 3.00000 1.00000 -2.00000 | -3.00000 ]
[ 1.00000 4.00000 3.00000 -1.00000 | -4.00000 ]
[ 2.00000 3.00000 -4.00000 -7.00000 | -3.00000 ]
[ 3.00000 8.00000 1.00000 -7.00000 | -8.00000 ]
rank{A}: 2
rank{B}: 2
答は無限 : ランク(A) == ランク(AB) < A行数
計算できません
◆◆◆◆ 消去法・逆行列計算1 ◆◆◆◆
入力: MATRIX:
[ 2.00000 | 1.00000 ]
rank{A}: 1
rank{B}: 1
答は一つ : ランク(A) == ランク(AB) == A行数
方程式の解法結果: MATRIX:
[ 0.50000 ]
行入れ替え: [0]
..逆行列検算..
numpy.inv() と同じ
◆◆◆◆ 消去法・逆行列計算2 ◆◆◆◆
入力: MATRIX:
[ -1.00000 1.00000 1.00000 | 1.00000 0.00000 0.00000 ]
[ 1.00000 -1.00000 1.00000 | 0.00000 1.00000 0.00000 ]
[ 1.00000 1.00000 -1.00000 | 0.00000 0.00000 1.00000 ]
rank{A}: 3
rank{B}: 3
答は一つ : ランク(A) == ランク(AB) == A行数
方程式の解法結果: MATRIX:
[ -0.00000 0.50000 0.50000 ]
[ 0.50000 0.00000 0.50000 ]
[ 0.50000 0.50000 0.00000 ]
行入れ替え: [0, 2, 1]
..逆行列検算..
numpy.inv() と同じ
◆◆◆◆ 消去法・逆行列計算3 ◆◆◆◆
入力: MATRIX:
[ 0.00000 -2.00000 0.00000 | 1.00000 0.00000 0.00000 ]
[ -1.00000 5.00000 2.00000 | 0.00000 1.00000 0.00000 ]
[ 0.00000 -1.00000 1.00000 | 0.00000 0.00000 1.00000 ]
rank{A}: 3
rank{B}: 3
答は一つ : ランク(A) == ランク(AB) == A行数
方程式の解法結果: MATRIX:
[ -3.50000 -1.00000 2.00000 ]
[ -0.50000 -0.00000 -0.00000 ]
[ -0.50000 0.00000 1.00000 ]
行入れ替え: [1, 0, 2]
..逆行列検算..
numpy.inv() と同じ
◆◆◆◆ 消去法・逆行列計算4 ◆◆◆◆
入力: MATRIX:
[ 1.00000 3.00000 9.00000 | 1.00000 0.00000 0.00000 ]
[ -1.00000 1.00000 -1.00000 | 0.00000 1.00000 0.00000 ]
[ 2.00000 -4.00000 -2.00000 | 0.00000 0.00000 1.00000 ]
rank{A}: 2
rank{B}: 3
答はなし : ランク(A) < ランク(AB)
計算できません
. . . . . . . . . .
---- another_elim.py ----
def chk(m):
'''
正方形、長方形行列 チェック
'''
if type(m) == list:
if len(m) == 0:
return None, 0, 0
else:
if type(m[0]) != list:
A = [m.copy()]
else:
A = [e.copy() for e in m]
n = len(A)
m = len(A[0])
else:
n = 0
m = 0
if m < n: # 正方行列,長方行列のみ
return None, 0, 0
return A, n, m
'''
参照:FORTRAN数値計算とプログラミング
国井利泰監修 中村明子、伊藤文子著 1971 共立出版
1.1 C 逆行列 EX1-1-C p-17 ~ 23
より、Fortranの手順をPythonに修正したもの。
入力: 方程式左辺行列+右辺行列(方程式の解法を行う) または、
方程式左辺行列+右辺単位行列(逆行列式計算を行う)
出力: 方程式回答結果行列
行入れ替え順列
処理タイプ: 単位行列
100 xxx
010 xxx
001 xxx
'''
def gj1(PA,n,m,E=1.0E-7):
if PA == None: # 有効な行列ではない
return None, None
A = [e.copy() for e in PA]
P = [_ for _ in range(n)]
for k in range(n):
# p is not zero
if abs(A[k][k]) < E: # チェック ゼロデバイド
for j in range(k+1, n):
if abs(A[j][k]) > abs(A[k][k]):
for ix in range(m):
xx = A[j][ix]
A[j][ix] = A[k][ix]
A[k][ix] = xx # 行を交換
xp = P[j]
P[j] = P[k]
P[k] = xp
break
else: # for j to n. ---|
return None, P # 逆行列なしエラー V
#
p = A[k][k]
for j in range(k,m):
A[k][j] /= p
for i in range(n):
if i == k:
continue
aik = A[i][k]
for j in range(k,m):
A[i][j] = A[i][j] - aik * A[k][j]
return [e[n:] for e in A], P
'''
参考:
サイエンスライブラリ情報電算機=20
FORTRANのよる 算法入門 一松信篇 一松信、伊藤二朗、管伊兵衛 著 サイエンス社 1974,1976
プログラム8.1
行列と行列式 古屋茂 著 培風館 1959,1966
付録1
入力: 方程式左辺行列+右辺行列(方程式の解法を行う) または、
方程式左辺行列+右辺単位行列(逆行列式計算を行う)
出力: 方程式回答結果行列
行入れ替え順列
処理タイプ: 1111 1.. 4111 1.. X4.. # b1-([0,1]*X3+[0,2]*X2+[0,3]*X1)/{1} = X4
1222 2.. ==> x322 2.. X3.. # b2-([1,2]*X2+[1,3]*X1)/{3} = X3
1233 3.. xx23 3.. X2.. # b3-([2,3]*X1)/{2} = X2
1234 4.. xxx1 4.. X1.. # b4/{1} = X1
'''
def eliminate(PA,n,n1,E=1.0E-7):
if PA == None: # 有効な行列ではない
return None, None
if n1 > (n*2) or n == n1:
return None,None
A = [e.copy() for e in PA]
X = [[0.0] * (n1-n) for _ in range(n)]
P = [_ for _ in range(n)]
for k in range(n):
ae = abs(A[k][k])
if k != (n-1):
k1 = k + 1
max = k
for i in range(k1,n):
if abs(A[i][k]) > ae:
max = i
ae = abs(A[i][k])
if max != k:
for j in range(k,n1):
ss = A[k][j]
A[k][j] = A[max][j]
A[max][j] = ss
tt = P[k]
P[k] = P[max]
P[max] = tt
if ae < E:
return None,P
pv = A[k][k]
if k == (n-1):
break
for i in range(k1,n):
w = A[i][k] / pv
for j in range(k1,n1):
A[i][j] -= (w * A[k][j])
for y in range(n1-n):
for l in range(n):
i = (n-1) - l
pv = A[i][i]
if abs(pv) < E:
return None,P
i1 = i + 1
w = A[i][n+y]
if l != 0:
for k in range(i1,n):
w -= (A[i][k] * X[k][y])
X[i][y] = w / pv
return X, P
def matrix_dmp(msg, MAT):
'''
行列の印刷
'''
print(msg, " MATRIX:")
if MAT is None:
print(" 結果がありません")
return
if len(MAT) == 0:
print("[ ]")
return
else:
if type(MAT[0]) == list:
A = [e.copy() for e in MAT]
else:
A = [MAT]
n = len(A)
nm = len(A[0])
for i in range(n):
print("[",end='')
if nm <= n:
for j in range(nm):
print(" % .5f" % (A[i][j]), end='')
else:
for j in range(n):
print(" % .5f" % (A[i][j]), end='')
print(" |",end='')
for j in range(n,nm):
print(" % .5f" % (A[i][j]), end='')
print(" ]")
if __name__ == "__main__":
import numpy as np
def ematrix(A):
n = len(A)
ma = []
for e in A:
ma.append(e[:n])
la = np.linalg.matrix_rank(ma)
lab = np.linalg.matrix_rank(A)
print("rank{A}:",la)
print("rank{B}:",lab)
if la == lab and la == n:
print("答は一つ : ランク(A) == ランク(AB) == A行数")
elif la == lab and la < n:
print("答は無限 : ランク(A) == ランク(AB) < A行数")
else:
print("答はなし : ランク(A) < ランク(AB)")
def check_inv(A,am):
n = len(A)
if n == 0:
return
if type(A[0]) == list:
MA = [e[:n] for e in A]
Mb = [e[n:] for e in A]
else:
n = 1
MA = [A[:n]]
Mb = [A[n:]]
if am != None:
if len(MA[0]) == len(Mb[0]):
#
# (注意)同じ列数の右辺に単位列を定義したら逆行列として検算をする。
#
ti = 1
for i in range(n):
if float(Mb[i][i]) != 1.0:
ti = 0
break
for j in range(len(Mb[0])):
if i != j and float(Mb[i][j]) != 0.0:
ti = 0
break
if ti:
print("..逆行列検算..")
if np.allclose(np.linalg.inv(MA), am):
print(" numpy.inv() と同じ")
else:
print(" 逆行列でない")
def test1(f,msg,A):
print("◆◆◆◆",msg,"◆◆◆◆")
matrix_dmp("入力:",A)
mA, n, m = chk(A)
if mA is not None:
ematrix(mA)
else:
print("計算できません")
return
am, cx = (eliminate(mA,n,m) if f == 1 else gj1(mA,n,m))
if am is None:
print("計算できません")
else:
matrix_dmp("方程式の解法結果:", am)
print("行入れ替え:", cx)
check_inv(mA,am)
print("")
print("*************")
print("*** TEST1 ***")
print("*************")
test1(0,"gj1数値例(0)",[])
test1(0,"gj1数値例(1)",[[2,3]])
test1(0,"gj1数値例(2)",[[1,0.99,1.99],[0.99,0.98,1.97]])
test1(0,"gj1数値例(3)",[[2,3,1,-3,1],[-1,2,2,4,6],[4,1,-3,5,3],[5,-4,-4,1,3]])
test1(0,"gj1 Rank(A) == Rank(A,b合わせた行列) < 4 ",[[1,3,1,-2,-3],[1,4,3,-1,-4],[2,3,-4,-7,-3],[3,8,1,-7,-8]])
test1(0,"gj1逆行列計算1",[2,1]) # 逆行列 右辺部分は単位行列のこと
test1(0,"gj1逆行列計算2",[[-1,1,1,1,0,0],[1,-1,1,0,1,0],[1,1,-1,0,0,1]]) # 逆行列 右辺部分は単位行列のこと
test1(0,"gj1逆行列計算3",[[0,-2,0,1,0,0],[-1,5,2,0,1,0],[0,-1,1,0,0,1]]) # 逆行列 右辺部分は単位行列のこと
test1(0,"gj1逆行列計算4",[[1,3,9,1,0,0],[-1,1,-1,0,1,0],[2,-4,-2,0,0,1]]) # 逆行列 右辺部分は単位行列のこと
#test1(0,"gj1逆行列計算5",[[2,3,1,-3,1,0,0,0],[-1,2,2,4,0,1,0,0],[4,1,-3,5,0,0,1,0],[5,-4,-4,1,0,0,0,1]]) # 逆行列 右辺部分は単位行列のこと
#test1(0,"gj1数値例(4)",[[]])
#test1(0,"gj1数値例(5)",[[1,2,3,2,2],[2,4,8,5,6],[4,1,1,7,7]])
#test1(0,"gj1数値例(6)",[[2.08,3.4,1.04,-0.28,1.28],[-1.68,-2.68,-0.84,0.16,-6.72],[5.14,3.12,-4.32,4.59,0.86],[3.12,2.8,1.56,1.88,4.62]])
print("")
print("*************")
print("*** TEST2 ***")
print("*************")
test1(1,"消去法・数値例(0)",[])
test1(1,"消去法・数値例(1)",[[2,3]])
test1(1,"消去法・数値例(2)",[[1,0.99,1.99],[0.99,0.98,1.97]])
test1(1,"消去法・数値例(3)",[[2,3,1,-3,1],[-1,2,2,4,6],[4,1,-3,5,3],[5,-4,-4,1,3]])
test1(1,"消去法・ Rank(A) == Rank(A,b合わせた行列) < 4 ",[[1,3,1,-2,-3],[1,4,3,-1,-4],[2,3,-4,-7,-3],[3,8,1,-7,-8]])
test1(1,"消去法・逆行列計算1",[2,1]) # 逆行列 右辺部分は単位行列のこと
test1(1,"消去法・逆行列計算2",[[-1,1,1,1,0,0],[1,-1,1,0,1,0],[1,1,-1,0,0,1]]) # 逆行列 右辺部分は単位行列のこと
test1(1,"消去法・逆行列計算3",[[0,-2,0,1,0,0],[-1,5,2,0,1,0],[0,-1,1,0,0,1]]) # 逆行列 右辺部分は単位行列のこと
test1(1,"消去法・逆行列計算4",[[1,3,9,1,0,0],[-1,1,-1,0,1,0],[2,-4,-2,0,0,1]]) # 逆行列 右辺部分は単位行列のこと
#test1(1,"消去法・逆行列計算5",[[2,3,1,-3,1,0,0,0],[-1,2,2,4,0,1,0,0],[4,1,-3,5,0,0,1,0],[5,-4,-4,1,0,0,0,1]]) # 逆行列 右辺部分は単位行列のこと
#test1(1,"消去法・数値例(4)",[[]])
#test1(1,"消去法・数値例(5)",[[1,2,3,2,2],[2,4,8,5,6],[4,1,1,7,7]])
#test1(1,"消去法・数値例(6)",[[2.08,3.4,1.04,-0.28,1.28],[-1.68,-2.68,-0.84,0.16,-6.72],[5.14,3.12,-4.32,4.59,0.86],[3.12,2.8,1.56,1.88,4.62]])
---------
2024-07-25 「mouspad メニューがない」
mousepadでメニューバーが消えてしまった。
CTRL+m を押したからでした。
キーバインドの設定は ~/.config/Mousepad/accels.scm にあり。
コマンドでは
gsettings list-recursively org.xfce.mousepad.preferences
で設定の一覧がでる。
gsettings set org.xfce.mousepad.preferences.window menubar-visible true
でメニューバーが表示され、mausepad実行中でもtrue/false で表示/非表示となる。
参照:
https://docs.xfce.org/apps/mousepad/start#keybindings
mousepadのヘルプページ
https://forum.xfce.org/viewtopic.php?id=9515
» [Solved] mousepad view menu option
2024-07-28 「行列・ガウスの消去法で方程式の解法」
ガウスの消去法で方程式の解法を試した。
WEB検索するといっぱい出てくるが、そのままではなかなか思っているようにはうまく行かない。
手で計算することを考えるとnumpy,scipyライブラリを使うと手順がよく見えなくなるので、
ライブラリを使わないで試した。
方程式の解法と逆行列,行列計算を計算した。
行列変形のかたちは色々あるが、行列計算もできる上三角行列をやってみた。
>>> a
array([[ 1, 3, 1, -2, -3],
[ 1, 4, 3, -1, -4],
[ 2, 3, -4, -7, -3],
[ 3, 8, 1, -7, -8]])
>>> np.linalg.matrix_rank(a)
2
>>> a
array([[ 1, 3, 1, -2],
[ 1, 4, 3, -1],
[ 2, 3, -4, -7],
[ 3, 8, 1, -7]])
>>> np.linalg.matrix_rank(a)
2
>>> a
array([[ 1, 3, 1, -2],
[ 1, 4, 3, -1],
[ 2, 3, -4, -7],
[ 3, 8, 1, -7]])
>>> b
array([-3, -4, -3, -8])
>>> np.linalg.solve(a,b)
array([ 2.04971182, -3.48414986, 2.07420749, -1.66426513])
Rank(A) == Rank(A,b合わせた行列) < len(A) の場合は、結果がでない。
実行:
$ python gauss1.py
◆◆◆◆ 数値例(1) ◆◆◆◆
入力: MATRIX:
[ ]
計算できません
関数内部: MATRIX:
[ ]
行入れ替え: [0]
My det(): 0.00000
numpy det(): None
◆◆◆◆ 数値例(2) ◆◆◆◆
入力: MATRIX:
[ 2.00000 | 3.00000 ]
方程式の解法結果: MATRIX:
[ 1.50000 ]
関数内部: MATRIX:
[ 2.00000 ]
行入れ替え: [0]
My det(): 2.00000
numpy det(): 2.00000
◆◆◆◆ 数値例(3) ◆◆◆◆
入力: MATRIX:
[ 1.00000 2.00000 3.00000 | 2.00000 2.00000 ]
[ 2.00000 4.00000 8.00000 | 5.00000 6.00000 ]
[ 4.00000 1.00000 1.00000 | 7.00000 7.00000 ]
方程式の解法結果: MATRIX:
[ 1.78571 1.85714 ]
[ -0.64286 -1.42857 ]
[ 0.50000 1.00000 ]
関数内部: MATRIX:
[ 4.00000 1.00000 1.00000 ]
[ 0.00000 3.50000 7.50000 ]
[ 0.00000 0.00000 -1.00000 ]
行入れ替え: [2, 1, 0]
My det(): 14.00000
numpy det(): 14.00000
◆◆◆◆ 数値例(4) ◆◆◆◆
入力: MATRIX:
[ 1.00000 0.99000 | 1.99000 ]
[ 0.99000 0.98000 | 1.97000 ]
方程式の解法結果: MATRIX:
[ 1.00000 ]
[ 1.00000 ]
関数内部: MATRIX:
[ 1.00000 0.99000 ]
[ 0.00000 -0.00010 ]
行入れ替え: [0, 1]
My det(): -0.00010
numpy det(): -0.00010
◆◆◆◆ 数値例(5) ◆◆◆◆
入力: MATRIX:
[ 2.08000 3.40000 1.04000 -0.28000 | 1.28000 ]
[ -1.68000 -2.68000 -0.84000 0.16000 | -6.72000 ]
[ 5.14000 3.12000 -4.32000 4.59000 | 0.86000 ]
[ 3.12000 2.80000 1.56000 1.88000 | 4.62000 ]
計算できません
関数内部: MATRIX:
[ 5.14000 3.12000 -4.32000 4.59000 ]
[ 0.00000 2.13743 2.78817 -2.13743 ]
[ 0.00000 0.00000 3.00023 -0.00000 ]
[ 0.00000 0.00000 0.00000 -0.00000 ]
行入れ替え: [2, 0, 3, 1]
My det(): 0.00000
numpy det(): 0.00000
◆◆◆◆ Rank(A) == Rank(A,b合わせた行列) < 4 ◆◆◆◆
入力: MATRIX:
[ 1.00000 3.00000 1.00000 -2.00000 | -3.00000 ]
[ 1.00000 4.00000 3.00000 -1.00000 | -4.00000 ]
[ 2.00000 3.00000 -4.00000 -7.00000 | -3.00000 ]
[ 3.00000 8.00000 1.00000 -7.00000 | -8.00000 ]
計算できません
関数内部: MATRIX:
[ 3.00000 8.00000 1.00000 -7.00000 ]
[ 0.00000 -2.33333 -4.66667 -2.33333 ]
[ 0.00000 -0.00000 -0.00000 -0.00000 ]
[ 0.00000 0.00000 -0.00000 -0.00000 ]
行入れ替え: [3, 2, 1, 0]
My det(): 0.00000
numpy det(): -0.00000
◆◆◆◆ 逆行列計算1 ◆◆◆◆
入力: MATRIX:
[ 2.00000 | 1.00000 ]
方程式の解法結果: MATRIX:
[ 0.50000 ]
関数内部: MATRIX:
[ 2.00000 ]
行入れ替え: [0]
My det(): 2.00000
numpy det(): 2.00000
逆行列検算 A@INV: MATRIX:
[ 1.00000 ]
numpy 逆行列: MATRIX:
[ 0.50000 ]
◆◆◆◆ 逆行列計算2 ◆◆◆◆
入力: MATRIX:
[ 0.00000 -2.00000 0.00000 | 1.00000 0.00000 0.00000 ]
[ -1.00000 5.00000 2.00000 | 0.00000 1.00000 0.00000 ]
[ 0.00000 -1.00000 1.00000 | 0.00000 0.00000 1.00000 ]
方程式の解法結果: MATRIX:
[ -3.50000 -1.00000 2.00000 ]
[ -0.50000 -0.00000 -0.00000 ]
[ -0.50000 0.00000 1.00000 ]
関数内部: MATRIX:
[ -1.00000 5.00000 2.00000 ]
[ 0.00000 -2.00000 0.00000 ]
[ 0.00000 0.00000 1.00000 ]
行入れ替え: [1, 0, 2]
My det(): -2.00000
numpy det(): -2.00000
◆◆◆◆ 逆行列計算3 ◆◆◆◆
入力: MATRIX:
[ 2.00000 3.00000 1.00000 -3.00000 | 1.00000 0.00000 0.00000 0.00000 ]
[ -1.00000 2.00000 2.00000 4.00000 | 0.00000 1.00000 0.00000 0.00000 ]
[ 4.00000 1.00000 -3.00000 5.00000 | 0.00000 0.00000 1.00000 0.00000 ]
[ 5.00000 -4.00000 -4.00000 1.00000 | 0.00000 0.00000 0.00000 1.00000 ]
方程式の解法結果: MATRIX:
[ 0.21053 0.22807 -0.10526 0.24561 ]
[ 0.06140 -0.16959 0.21930 -0.23392 ]
[ 0.18421 0.49123 -0.34211 0.29825 ]
[ -0.07018 0.14620 0.03509 0.02924 ]
関数内部: MATRIX:
[ 5.00000 -4.00000 -4.00000 1.00000 ]
[ 0.00000 4.60000 2.60000 -3.40000 ]
[ 0.00000 0.00000 -2.17391 7.30435 ]
[ 0.00000 0.00000 0.00000 6.84000 ]
行入れ替え: [3, 0, 2, 1]
My det(): -342.00000
numpy det(): -342.00000
◆◆◆◆ 逆行列計算4 ◆◆◆◆
入力: MATRIX:
[ 0.00000 -2.00000 0.00000 | 1.00000 0.00000 0.00000 ]
[ -1.00000 5.00000 2.00000 | 0.00000 1.00000 0.00000 ]
[ 0.00000 -1.00000 1.00000 | 0.00000 0.00000 1.00000 ]
方程式の解法結果: MATRIX:
[ -3.50000 -1.00000 2.00000 ]
[ -0.50000 -0.00000 -0.00000 ]
[ -0.50000 0.00000 1.00000 ]
関数内部: MATRIX:
[ -1.00000 5.00000 2.00000 ]
[ 0.00000 -2.00000 0.00000 ]
[ 0.00000 0.00000 1.00000 ]
行入れ替え: [1, 0, 2]
My det(): -2.00000
numpy det(): -2.00000
◆◆◆◆ 逆行列計算5 ◆◆◆◆
入力: MATRIX:
[ 1.00000 3.00000 9.00000 | 1.00000 0.00000 0.00000 ]
[ -1.00000 1.00000 -1.00000 | 0.00000 1.00000 0.00000 ]
[ 2.00000 -4.00000 -2.00000 | 0.00000 0.00000 1.00000 ]
計算できません
関数内部: MATRIX:
[ 2.00000 -4.00000 -2.00000 ]
[ 0.00000 5.00000 10.00000 ]
[ 0.00000 0.00000 0.00000 ]
行入れ替え: [2, 0, 1]
My det(): 0.00000
numpy det(): 0.00000
◆◆◆◆ 行列計算1 ◆◆◆◆
入力: MATRIX:
[ -6.00000 -2.00000 -9.00000 -2.00000 ]
[ -10.00000 3.00000 -8.00000 11.00000 ]
[ 7.00000 -9.00000 -9.00000 5.00000 ]
[ -11.00000 8.00000 5.00000 5.00000 ]
方程式の解法結果: MATRIX:
[ ]
[ ]
[ ]
[ ]
関数内部: MATRIX:
[ -11.00000 8.00000 5.00000 5.00000 ]
[ 0.00000 -6.36364 -11.72727 -4.72727 ]
[ 0.00000 0.00000 -4.67143 9.62857 ]
[ 0.00000 0.00000 0.00000 13.94190 ]
行入れ替え: [3, 0, 1, 2]
My det(): 4559.00000
numpy det(): 4559.00000
◆◆◆◆ 行列計算2 ◆◆◆◆
入力: MATRIX:
[ 1.00000 -1.00000 -1.00000 ]
[ -1.00000 1.00000 -1.00000 ]
[ -1.00000 -1.00000 1.00000 ]
方程式の解法結果: MATRIX:
[ ]
[ ]
[ ]
関数内部: MATRIX:
[ 1.00000 -1.00000 -1.00000 ]
[ 0.00000 -2.00000 0.00000 ]
[ 0.00000 0.00000 -2.00000 ]
行入れ替え: [0, 2, 1]
My det(): -4.00000
numpy det(): -4.00000
◆◆◆◆ 行列計算3 ◆◆◆◆
入力: MATRIX:
[ -1.00000 1.00000 3.00000 ]
[ 2.00000 3.00000 -1.00000 ]
[ 3.00000 4.00000 -2.00000 ]
計算できません
関数内部: MATRIX:
[ 3.00000 4.00000 -2.00000 ]
[ 0.00000 2.33333 2.33333 ]
[ 0.00000 0.00000 -0.00000 ]
行入れ替え: [2, 0, 1]
My det(): 0.00000
numpy det(): -0.00000
............................
---- gauss1.py --------
'''
参考:
http://www.nct9.ne.jp/m_hiroi/light/numpy03.html
お気楽 NumPy プログラミング超入門
サイエンスライブラリ情報電算機=20 FORTRANによる算法入門 / 一松信篇 一松信、伊藤二朗、管伊兵衛 著 サイエンス社 1974,1976
プログラム 8.1, 8.2
入力: 方程式左辺行列+右辺行列(方程式の解法を行う) または、
方程式左辺行列+右辺単位行列(逆行列式計算を行う) または、
方程式左辺行列(行列式計算を行う)
出力: 方程式回答結果行列
関数内部Matrix行列
行入れ替え順列
行列式の値
処理タイプ 上三角行列
xxx
0xx
00x
'''
def pivot(xs, i, n, m, P):
'''
行入れ替え
'''
c = 0
p = i
q = abs(xs[i][i])
for s in range(i,n):
if q < abs(xs[s][i]):
p = s
q = abs(xs[s][i])
if p != i:
for j in range(m):
temp = xs[i][j]
xs[i][j] = xs[p][j]
xs[p][j] = temp
temp = P[i] # 行入れ替え情報
P[i] = P[p]
P[p] = temp
c += 1
return c
def gauss1(PA, E=1.0E-5):
'''
ガウスの消去法
'''
if type(PA) == list:
if type(PA[0]) != list:
zs = [PA.copy()]
else:
zs = [e.copy() for e in PA]
n = len(zs)
m = len(zs[0])
P = [_ for _ in range(n)]
else:
n = 0
m = 0
if m > (n*2) or m == 0: # 右辺は行数と同じ列数まで
return None, None, None, 0.0
cc = 0
for i in range(n - 1):
cc += pivot(zs, i, n, m, P)
if abs(zs[i][i]) < E:
return None, [e[:n] for e in zs], P, 0.0
for j in range(i + 1, n):
temp = zs[j][i] / zs[i][i]
for s in range(i,m):
zs[j][s] -= temp * zs[i][s]
det = 1;
for i in range(n):
if abs(zs[i][i]) < E:
return None,[e[:n] for e in zs], P, 0.0
det *= zs[i][i]
if cc & 1:
det *= -1
for c in range(n,m):
for i in range(n - 1, -1, -1):
if (i+1) < n:
for j in range(i,n-1):
zs[i][c] -= zs[i][j+1] * zs[j+1][c]
zs[i][c] /= zs[i][i]
return [e[n:] for e in zs],[e[:n] for e in zs], P, det
def matrix_dmp(msg, MAT):
'''
行列の印刷
'''
print(msg, " MATRIX:")
if MAT is None:
print(" 結果がありません")
return
if type(MAT[0]) == list:
A = [e.copy() for e in MAT]
else:
A = [MAT]
n = len(A)
nm = len(A[0])
for i in range(n):
print("[",end='')
if nm <= n:
for j in range(nm):
print(" % .5f" % (A[i][j]), end='')
else:
for j in range(n):
print(" % .5f" % (A[i][j]), end='')
print(" |",end='')
for j in range(n,nm):
print(" % .5f" % (A[i][j]), end='')
print(" ]")
if __name__ == "__main__":
import numpy as np
def permutation(P):
'''
順列 交換回数計算
'''
n = len(P)
Z = [e for e in P]
cnt = 0
for i in range(n):
if Z[i] != i:
min = i
for j in range(i+1,n):
if Z[j] < Z[min]:
min = j
xx = Z[min]
Z[min] = Z[i]
Z[i] = xx
cnt += 1
return cnt
def test(msg,A):
print("◆◆◆◆",msg,"◆◆◆◆")
matrix_dmp("入力:",A)
am, im, cx, det = gauss1(A)
if am is None:
print("計算できません")
else:
matrix_dmp("方程式の解法結果:", am)
matrix_dmp("関数内部:", im)
print("行入れ替え:", cx)
print("My det(): % .5f" % (det))
n = len(A)
if type(A[0]) == list:
MA = [e[:n] for e in A]
Mb = [e[n:] for e in A]
else:
n = 1
MA = [A[:n]]
Mb = [A[n:]]
if len(MA[0]) > 0:
print("numpy det(): % .5f" % (np.linalg.det(MA)))
else:
print("numpy det(): None")
if im != None and det > 0.0:
if len(MA[0]) == len(Mb[0]):
#
# (注意)同じ列数の右辺に単位列を定義したら逆行列として検算をする。
#
ti = 1
for i in range(n):
if float(Mb[i][i]) != 1.0:
ti = 0
break
for j in range(len(Mb[0])):
if i != j and float(Mb[i][j]) != 0.0:
ti = 0
break
if ti:
kn = np.dot(MA,am).tolist()
matrix_dmp("逆行列検算 A@INV:",kn)
matrix_dmp("numpy 逆行列:", np.linalg.inv(MA).tolist())
test("数値例(1)",[[]])
test("数値例(2)",[[2,3]])
test("数値例(3)",[[1,2,3,2,2],[2,4,8,5,6],[4,1,1,7,7]])
test("数値例(4)",[[1,0.99,1.99],[0.99,0.98,1.97]])
test("数値例(5)",[[2.08,3.4,1.04,-0.28,1.28],[-1.68,-2.68,-0.84,0.16,-6.72],[5.14,3.12,-4.32,4.59,0.86],[3.12,2.8,1.56,1.88,4.62]])
test("Rank(A) == Rank(A,b合わせた行列) < 4 ",[[1,3,1,-2,-3],[1,4,3,-1,-4],[2,3,-4,-7,-3],[3,8,1,-7,-8]])
test("逆行列計算1",[2,1]) # 逆行列 右辺部分は単位行列のこと
test("逆行列計算2",[[0,-2,0,1,0,0],[-1,5,2,0,1,0],[0,-1,1,0,0,1]]) # 逆行列 右辺部分は単位行列のこと
test("逆行列計算3",[[2,3,1,-3,1,0,0,0],[-1,2,2,4,0,1,0,0],[4,1,-3,5,0,0,1,0],[5,-4,-4,1,0,0,0,1]]) # 逆行列 右辺部分は単位行列のこと
test("逆行列計算4",[[0,-2,0,1,0,0], [-1,5,2,0,1,0], [0,-1, 1,0,0,1]]) # 逆行列 右辺部分は単位行列のこと
test("逆行列計算5",[[1,3,9,1,0,0],[-1,1,-1,0,1,0],[2,-4,-2,0,0,1]]) # 逆行列 右辺部分は単位行列のこと
test("行列計算1",[[-6,-2,-9,-2],[-10,3,-8,11],[7,-9,-9,5],[-11,8,5,5]]) #
test("行列計算2",[[1,-1,-1],[-1,1,-1],[-1,-1,1]])
test("行列計算3",[[-1,1,3],[2,3,-1],[3,4,-2]])
....................................................................................................
2024-07-26 「行列・階数(Rank)計算」
階数
方程式 AX=b
A: b:
2 3 1 -3 | 1
-1 2 2 4 | 6
4 1 -3 5 | 3
5 -4 -4 1 | 3
Rank(A) == Rank(A,b合わせた行列) == len(A)
解が1組
Rank(A) == Rank(A,b合わせた行列) < len(A)
解が多い
Rank(A) != Rank(A,b合わせた行列)
解がない
Rank(A) < len(A)
逆行列がない
行列の階数計算をやってみた。
実行:
$ python rank10n.py
--
Matrix: - 2 x 0
[ ]
[ ]
Rank is: 0
--
Matrix: - 1 x 1
[ 1 ]
Rank is: 1
np.rank: 1
--
Matrix: - 1 x 1
[ 2 ]
Rank is: 1
np.rank: 1
--
Matrix: - 1 x 2
[ 2 , 3 ]
Rank is: 1
np.rank: 1
--
Matrix: - 1 x 0
[ ]
Rank is: 0
--
Matrix: - 3 x 3
[ 0 , 0 , 0 ]
[ 0 , 0 , 0 ]
[ 0 , 0 , 0 ]
Rank is: 0
np.rank: 0
--
Matrix: - 3 x 3
[ 0 , 0 , 1 ]
[ 0 , 0 , 0 ]
[ 1 , 0 , 0 ]
Rank is: 2
np.rank: 2
--
Matrix: - 3 x 3
[ 1 , 0 , 0 ]
[ 0 , 1 , 0 ]
[ 0 , 0 , 1 ]
Rank is: 3
np.rank: 3
--
Matrix: - 3 x 3
[ 0 , -2 , 0 ]
[ -1 , 5 , 2 ]
[ 0 , -1 , 1 ]
Rank is: 3
np.rank: 3
--
Matrix: - 3 x 3
[ 1 , 3 , 9 ]
[ -1 , 1 , -1 ]
[ 2 , -4 , -2 ]
Matrix in Rank Function: - 3 x 3
[ 1.0 , 0.0 , 3.0 ]
[ 0.0 , 4.0 , 8.0 ]
[ 0.0 , 0.0 , 0.0 ]
Rank is: 2
np.rank: 2
--
Matrix: - 4 x 5
[ 1 , 3 , 1 , -2 , -3 ]
[ 1 , 4 , 3 , -1 , -4 ]
[ 2 , 3 , -4 , -7 , -3 ]
[ 3 , 8 , 1 , -7 , -8 ]
Matrix in Rank Function: - 4 x 5
[ 1.0 , 0.0 , 0.0 , -5.0 , 0.0 ]
[ 0.0 , 1.0 , -1.0 , 1.0 , -1.0 ]
[ 0.0 , 0.0 , 0.0 , 0.0 , 0.0 ]
[ 0.0 , 0.0 , 0.0 , 0.0 , 0.0 ]
Rank is: 2
np.rank: 2
--
Matrix: - 3 x 4
[ 1 , 1 , -2 , 1 ]
[ 1 , -2 , 1 , 1 ]
[ -2 , 1 , 1 , 1 ]
Matrix in Rank Function: - 3 x 4
[ 1.0 , 0.0 , 0.0 , 1.0 ]
[ 0.0 , -3.0 , 0.0 , 0.0 ]
[ 0.0 , 0.0 , 0.0 , 3.0 ]
Rank is: 3
np.rank: 3
--
Matrix: - 3 x 3
[ 1 , 1 , -2 ]
[ 1 , -2 , 1 ]
[ -2 , 1 , 1 ]
Rank is: 2
np.rank: 2
--
Matrix: - 2 x 3
[ 1 , 2 , 3 ]
[ 4 , 5 , 6 ]
Matrix in Function: - 2 x 3
[ 1.0 , 0.5 , 0.0 ]
[ 0.0 , 0.0 , 0.0 ] <<===3行目だとして処理した結果
Rank is: 2
np.rank: 2
...
---- rank10n.py ---
'''
参照:
https://www.geeksforgeeks.org/program-for-rank-of-matrix/
Program for Rank of Matrix
'''
# ----------------------
# Exchange Row in matrix
#
def swap(Matrix, row1, row2, col):
for i in range(col):
temp = Matrix[row1][i]
Matrix[row1][i] = Matrix[row2][i]
Matrix[row2][i] = temp
# ----------------
# Display matrix
#
def Display(msg, Mtx):
if type(Mtx[0]) == list:
Matrix = [e.copy() for e in Mtx]
else:
Matrix = [Mtx]
col = 1
row = len(Matrix)
col = len(Matrix[0])
print(msg," - ",row," x ",col)
for i in range(row):
print("[ ", end='')
for j in range(col):
if j != 0:
print(" , ",end='')
print (str(Matrix[i][j]),end='')
print (' ]')
# ----------------
# Rank of a matrix
#
def rank2fMatrix(A, inf=0):
if type(A) != list:
return 0
if type(A[0]) != list:
Matrix = [A.copy()]
else:
Matrix = [e.copy() for e in A]
rank = len(Matrix[0])
C = rank
R = len(Matrix)
###Matrix = [e.copy() for e in A]
for row in range(0, rank, 1):
if row >= R:
row1 = R-1
if Matrix[row1][row] != 0:
for col in range(0, R, 1):
if col != row:
multiplier = (Matrix[col][row] / Matrix[row1][row])
for i in range(rank):
Matrix[col][i] -= (multiplier * Matrix[row1][i])
if Matrix[row1][row] == 0 and row == (C-1):
rank -= 1
continue
if Matrix[row][row] != 0:
for col in range(0, R, 1):
if col != row:
multiplier = (Matrix[col][row] / Matrix[row][row])
for i in range(rank):
Matrix[col][i] -= (multiplier * Matrix[row][i])
else:
reduce = True
for i in range(row + 1, R, 1):
if Matrix[i][row] != 0:
swap(Matrix, row, i, rank)
reduce = False
break
if reduce:
rank -= 1
# copy the last column here
for i in range(0, R, 1):
Matrix[i][row] = Matrix[i][rank]
row -= 1
if inf == 1:
return rank, Matrix
else:
return (rank)
# -------------------
# Test Main
#
if __name__ == '__main__':
import numpy as np
m = [[],[]]
Display("--\nMatrix:",m)
print ("Rank is:", (rank2fMatrix(m)))
#print("np.rank:",np.linalg.matrix_rank(m))
m = [[1]]
Display("--\nMatrix:",m)
print ("Rank is:", (rank2fMatrix(m)))
print("np.rank:",np.linalg.matrix_rank(m))
m = [2]
Display("--\nMatrix:",m)
print ("Rank is:", (rank2fMatrix(m)))
print("np.rank:",np.linalg.matrix_rank(m))
m = [2,3]
Display("--\nMatrix:",m)
print ("Rank is:", (rank2fMatrix(m)))
print("np.rank:",np.linalg.matrix_rank(m))
m = [[]]
Display("--\nMatrix:",m)
print ("Rank is:", (rank2fMatrix(m)))
#print("np.rank:",np.linalg.matrix_rank(m))
m = [[0,0,0],[0,0,0],[0,0,0]]
Display("--\nMatrix:",m)
print ("Rank is:", (rank2fMatrix(m)))
print("np.rank:",np.linalg.matrix_rank(m))
m = [[0,0,1],[0,0,0],[1,0,0]]
Display("\n--\nMatrix:",m)
print ("Rank is:", (rank2fMatrix(m)))
print("np.rank:",np.linalg.matrix_rank(m))
m = [[1,0,0],[0,1,0],[0,0,1]]
Display("--\nMatrix:",m)
print ("Rank is:", (rank2fMatrix(m)))
print("np.rank:",np.linalg.matrix_rank(m))
m = [[0,-2,0],[-1,5,2],[0,-1,1]]
Display("--\nMatrix:",m)
print ("Rank is:", (rank2fMatrix(m)))
print("np.rank:",np.linalg.matrix_rank(m))
m = [[1,3,9],[-1,1,-1],[2,-4,-2]]
Display("--\nMatrix:",m)
rnk , mat = rank2fMatrix(m, inf=1)
Display("Matrix in Rank Function:",mat)
print("Rank is:",rnk)
print("np.rank:",np.linalg.matrix_rank(m))
m = [[1, 3, 1, -2, -3], [1, 4, 3, -1, -4], [2, 3, -4, -7, -3], [3, 8, 1, -7, -8]]
Display("--\nMatrix:",m)
rnk , mat = rank2fMatrix(m, inf=1)
Display("Matrix in Rank Function:",mat)
print("Rank is:",rnk)
print("np.rank:",np.linalg.matrix_rank(m))
m = [[1, 1, -2, 1], [1, -2, 1, 1], [-2, 1, 1, 1]]
Display("--\nMatrix:",m)
rnk, mat = rank2fMatrix(m, inf=1)
Display("Matrix in Rank Function:",mat)
print("Rank is:",rnk)
print("np.rank:",np.linalg.matrix_rank(m))
m = [[1, 1, -2], [1, -2, 1], [-2, 1, 1]]
Display("--\nMatrix:",m)
rnk = rank2fMatrix(m)
print("Rank is:",rnk)
print("np.rank:",np.linalg.matrix_rank(m))
m = [[1,2,3],[4,5,6]]
Display("--\nMatrix:",m)
rnk, mat = rank2fMatrix(m, inf=1)
Display("Matrix in Function:",mat)
print("Rank is:",rnk)
print("np.rank:",np.linalg.matrix_rank(m))
---
参照:
https://www.geeksforgeeks.org/program-for-rank-of-matrix/
Program for Rank of Matrix
https://github.com/TheAlgorithms/Python/tree/master/linear_algebra
Linear algebra library for Python
src/rank_of_matrix.py
技術者のための空学の要点1 線形数学・計算法 唐沢英雄 著 理工図書 1982,1984
2024-08-26 「行列 LU分解・行列式計算・方程式解法」
参考:
(1)初等線形代数 --考え方と応用プログラム
石原辰雄・長谷川勝也 著 共立出版 1986,1988
(2)https://stackoverflow.com/questions/28441509/how-to-implement-lu-decomposition-with-partial-pivoting-in-python
How to implement LU decomposition with partial pivoting in Python?
(3)https://nttdocomo-developers.jp/entry/2024/02/17/090000
スバラしき逆行列の世界 (LU分解)
行列のLU分解と同時に行列式計算もやってみた。
10x10行列以上の大きいものは計算方法によってはものすごく遅くなる。
追加機能:
方程式解法、逆行列
プログラム追加分
---
"""
https://johnfoster.pge.utexas.edu/numerical-methods-book/LinearAlgebra_LU.html
のなかの
lu_solve
"""
def forward_substitution(L, b):
#Get number of rows
n = len(L)
#Allocating space for the solution vector
#y = np.zeros_like(b, dtype=np.double);
y = [0 for _ in range(n)]
#Here we perform the forward-substitution.
#Initializing with the first row.
y[0] = b[0] / L[0][0]
#Looping over rows in reverse (from the bottom up),
#starting with the second to last row, because the
#last row solve was completed in the last step.
for i in range(1, n):
# y[i] = (b[i] - np.dot(L[i,:i], y[:i])) / L[i,i]
sum = 0
for j in range(i):
sum += L[i][j] * y[j]
y[i] = (b[i] - sum) / L[i][i]
return y
def back_substitution(U, y):
#UU = U.tolist()
#Number of rows
n = len(U)
#Allocating space for the solution vector
x = [0 for _ in range(n)]
#Here we perform the back-substitution.
#Initializing with the last row.
x[n-1] = y[n-1] / U[n-1][n-1]
#Looping over rows in reverse (from the bottom up),
#starting with the second to last row, because the
#last row solve was completed in the last step.
for i in range(n-2, -1, -1):
#x[i] = (y[i] - np.dot(U[i,i:], x[i:])) / U[i,i]
sum = 0
for j in range(i+1,n):
sum += U[i][j] * x[j]
x[i] = (y[i] - sum) / U[i][i]
return x
def lu_solve(A, b):
n = len(A)
P, L, U = lu(A,n)
if L == None:
return None, None
mb = [e for e in b]
xchange(mb, P)
y = forward_substitution(L, mb)
x = back_substitution(U, y)
return x
# ^^^^^^^^^^^^
def xchange(B, P):
'''
順列 交換回数計算
'''
n = len(B)
Z = [e for e in P]
cnt = 0
for i in range(n):
if Z[i] != i:
min = i
for j in range(i+1,n):
if Z[j] < Z[min]:
min = j
xx = Z[min]
Z[min] = Z[i]
Z[i] = xx
cnt += 1
bb = [e for e in B]
for i in range(n):
B[i] = bb[P[i]]
return cnt
def plu_inverse(PA):
n = len(PA)
INV = [[0 for _ in range(n)] for _ in range(n)]
for i in range(n):
b = [0.0 if k != i else 1 for k in range(n)]
x = lu_solve(PA, b)
if x is None:
return None
for ln in range(n):
INV[ln][i] = x[ln]
return INV
# ------
x = lu_solve([[1,2,3],[2,4,8],[4,1,1]],[2,5,7])
print("答:",x)
print("逆行列")
print( plu_inverse([[1,2,3],[2,4,8],[4,1,1]]) )
---
結果
...
答: [1.7857142857142858, -0.6428571428571429, 0.5]
逆行列
[[-0.2857142857142857, 0.07142857142857142, 0.2857142857142857], [2.142857142857143, -0.7857142857142857, -0.14285714285714285], [-1.0, 0.5, -0.0]]
...
python では、
>>> import numpy as np
>>> a = [[1, 2, 3], [2, 4, 8], [4, 1, 1]]
>>> b = [2, 5, 7]
>>> np.linalg.solve(a,b)
array([ 1.78571429, -0.64285714, 0.5 ])
>>> np.linalg.inv(a)
array([[-0.28571429, 0.07142857, 0.28571429],
[ 2.14285714, -0.78571429, -0.14285714],
[-1. , 0.5 , -0. ]])
................................................
上記の追加プログラムは以下のソースプログラムに追加する。
実行:
$ python TYP-LU-det.py
計算−1 ● ***Results***
Used A ---
[[2, 3, 1, -3], [-1, 2, 2, 4], [4, 1, -3, 5], [5, -4, -4, 1]]
**Answers**
numpy RANK: 4
L1: MATRIX:
1.0000 0.0000 0.0000 0.0000
0.4000 1.0000 0.0000 0.0000
0.8000 0.9130 1.0000 0.0000
-0.2000 0.2609 -0.2400 1.0000
U1: MATRIX:
5.0000 -4.0000 -4.0000 1.0000
0.0000 4.6000 2.6000 -3.4000
0.0000 0.0000 -2.1739 7.3043
0.0000 0.0000 0.0000 6.8400
行入れ替え情報: [3, 0, 2, 1]
DET: -342.00000000000006
numpy det: -342.00000000000017
..検算..
det() OK
matrix OK
計算−2 ● ***Results***
Used A ---
[[2, 0], [0, 5]]
**Answers**
numpy RANK: 2
L1: MATRIX:
1.0000 0.0000
0.0000 1.0000
U1: MATRIX:
2.0000 0.0000
0.0000 5.0000
行入れ替え情報: [0, 1]
DET: 10.0
numpy det: 9.999999999999998
..検算..
det() OK
matrix OK
計算−3 ● ***Results***
Used A ---
[[0.0, 1.0], [1.0, 0.0]]
**Answers**
numpy RANK: 2
L1: MATRIX:
1.0000 0.0000
0.0000 1.0000
U1: MATRIX:
1.0000 0.0000
0.0000 1.0000
行入れ替え情報: [1, 0]
DET: -1.0
numpy det: -1.0
..検算..
det() OK
matrix OK
計算−4 ● ***Results***
Used A ---
[[4]]
**Answers**
numpy RANK: 1
L1: MATRIX:
1.0000
U1: MATRIX:
4.0000
行入れ替え情報: [0]
DET: 4
numpy det: 4.0
..検算..
det() OK
matrix OK
計算−5 ● ***Results***
Used A ---
[0.0]
**Answers**
numpy RANK: 0
L1: MATRIX:
1.0000
U1: MATRIX:
0.0000
行入れ替え情報: [0]
DET: 0.0
DET() == ZERO
numpy det: 0.0
..検算..
det() OK
matrix OK
計算−6 ● ***Results***
Used A ---
[[-1, 1, 3], [2, 3, -1], [3, 4, -2]]
**Answers**
numpy RANK: 2
L1: MATRIX:
1.0000 0.0000 0.0000
-0.3333 1.0000 0.0000
0.6667 0.1429 1.0000
U1: MATRIX:
3.0000 4.0000 -2.0000
0.0000 2.3333 2.3333
0.0000 0.0000 -0.0000
行入れ替え情報: [2, 0, 1]
DET: -1.9428902930940236e-15
DET() == ZERO
numpy det: -1.896631000401315e-15
..検算..
det() OK
matrix OK
計算−7 ● ***Results***
Used A ---
[[1, 3, 9], [-1, 1, -1], [2, -4, -2]]
**Answers**
numpy RANK: 2
L1: MATRIX:
1.0000 0.0000 0.0000
0.5000 1.0000 0.0000
-0.5000 -0.2000 1.0000
U1: MATRIX:
2.0000 -4.0000 -2.0000
0.0000 5.0000 10.0000
0.0000 0.0000 0.0000
行入れ替え情報: [2, 0, 1]
DET: 0.0
DET() == ZERO
numpy det: 1.1102230246251546e-15
..検算..
det() OK
matrix OK
計算−8 ● ***Results***
Used A ---
[[1, -1, -1], [-1, 1, -1], [-1, -1, 1]]
**Answers**
numpy RANK: 3
L1: MATRIX:
1.0000 0.0000 0.0000
-1.0000 1.0000 0.0000
-1.0000 -0.0000 1.0000
U1: MATRIX:
1.0000 -1.0000 -1.0000
0.0000 -2.0000 0.0000
0.0000 0.0000 -2.0000
行入れ替え情報: [0, 2, 1]
DET: -4.0
numpy det: -4.0
..検算..
det() OK
matrix OK
計算-9 ● ***Results***
Used A ---
[[-5, -1, 10, -10], [-9, 3, -9, -7], [9, -4, -10, 0], [-3, 7, 7, -9]]
**Answers**
numpy RANK: 4
L1: MATRIX:
1.0000 0.0000 0.0000 0.0000
0.3333 1.0000 0.0000 0.0000
0.5556 -0.4444 1.0000 0.0000
-1.0000 -0.1667 -0.8914 1.0000
U1: MATRIX:
-9.0000 3.0000 -9.0000 -7.0000
0.0000 6.0000 10.0000 -6.6667
0.0000 0.0000 19.4444 -9.0741
0.0000 0.0000 0.0000 -16.2000
行入れ替え情報: [1, 3, 0, 2]
DET: -17010.0
numpy det: -17010.000000000004
..検算..
det() OK
matrix OK
計算−10 ● ***Results***
Used A ---
[[0, -2, 0], [-1, 5, 2], [0, -1, 1]]
**Answers**
numpy RANK: 3
L1: MATRIX:
1.0000 0.0000 0.0000
-0.0000 1.0000 0.0000
-0.0000 0.5000 1.0000
U1: MATRIX:
-1.0000 5.0000 2.0000
0.0000 -2.0000 0.0000
0.0000 0.0000 1.0000
行入れ替え情報: [1, 0, 2]
DET: -2.0
numpy det: -2.0
..検算..
det() OK
matrix OK
計算−11 ● ***Results***
Used A ---
[[0, 0, 3], [-1, 5, 2], [0, -1, 2]]
**Answers**
numpy RANK: 3
L1: MATRIX:
1.0000 0.0000 0.0000
-0.0000 1.0000 0.0000
-0.0000 -0.0000 1.0000
U1: MATRIX:
-1.0000 5.0000 2.0000
0.0000 -1.0000 2.0000
0.0000 0.0000 3.0000
行入れ替え情報: [1, 2, 0]
DET: 3.0
numpy det: 3.0000000000000004
..検算..
det() OK
matrix OK
計算−12 ● ***Results***
Used A ---
[[1, 2, 2], [2, 1, 2], [2, 2, 1]]
**Answers**
numpy RANK: 3
L1: MATRIX:
1.0000 0.0000 0.0000
0.5000 1.0000 0.0000
1.0000 0.6667 1.0000
U1: MATRIX:
2.0000 1.0000 2.0000
0.0000 1.5000 1.0000
0.0000 0.0000 -1.6667
行入れ替え情報: [1, 0, 2]
DET: 5.0
numpy det: 4.999999999999998
..検算..
det() OK
matrix OK
計算−13 ● ***Results***
Used A ---
[[0.0, -1.0, 1.0, 0.0, -1.0], [4.0, 4.0, 2.0, 1.0, 1.0], [4.0, 1.0, 1.0, 3.0, 2.0], [0.0, 3.0, -1.0, 4.0, -2.0], [-1.0, -1.0, -1.0, -1.0, -1.0]]
**Answers**
numpy RANK: 5
L1: MATRIX:
1.0000 0.0000 0.0000 0.0000 0.0000
1.0000 1.0000 0.0000 0.0000 0.0000
0.0000 -1.0000 1.0000 0.0000 0.0000
0.0000 0.3333 -0.6667 1.0000 0.0000
-0.2500 -0.0000 0.2500 -0.6750 1.0000
U1: MATRIX:
4.0000 4.0000 2.0000 1.0000 1.0000
0.0000 -3.0000 -1.0000 2.0000 1.0000
0.0000 0.0000 -2.0000 6.0000 -1.0000
0.0000 0.0000 0.0000 3.3333 -2.0000
0.0000 0.0000 0.0000 0.0000 -1.8500
行入れ替え情報: [1, 2, 3, 0, 4]
DET: 148.0
numpy det: 147.99999999999994
..検算..
det() OK
matrix OK
o o o o o o o
TEST MATRIX No. 1
38 x 38 行列
numpy RANK: 38
..検算:
det() OK
matrix OK
TEST MATRIX No. 2
19 x 19 行列
numpy RANK: 19
..検算:
det() OK
matrix OK
TEST MATRIX No. 3
34 x 34 行列
numpy RANK: 34
..検算:
det() OK
matrix OK
TEST MATRIX No. 4
38 x 38 行列
numpy RANK: 38
..検算:
det() OK
matrix OK
TEST MATRIX No. 5
19 x 19 行列
numpy RANK: 19
..検算:
det() OK
matrix OK
〜〜〜〜〜〜〜〜〜〜〜〜〜
プログラム:
--- TYP-LU-det.py ----
'''
(1)初等線形代数 --考え方と応用プログラム
石原辰雄・長谷川勝也 著 共立出版 1986,1988
LU分解 *LU
(2)https://stackoverflow.com/questions/28441509/how-to-implement-lu-decomposition-with-partial-pivoting-in-python
How to implement LU decomposition with partial pivoting in Python?
lu_factor()
'''
def lu(m,EPS=1.0e-7):
A = [e.copy() for e in m]
n = len(A)
PZ = [i for i in range(n)]
for i in range(n-1):
amax = abs(A[i][i])
kmax = i
for k in range(i+1,n):
ww = abs(A[k][i])
if ww > amax:
amax = ww
kmax = k
if amax < EPS:
return None, None, None
if kmax != i:
for j in range(n):
xx = A[i][j]
A[i][j] = A[kmax][j]
A[kmax][j] = xx
xx = PZ[i]
PZ[i] = PZ[kmax]
PZ[kmax] = xx
aii = A[i][i]
for k in range(i+1,n):
mm = A[k][i] / aii
A[k][i] = mm
for j in range(i+1,n):
A[k][j] = A[k][j] - mm * A[i][j]
# U
U = [e.copy() for e in A]
for i in range(n):
for j in range(i):
U[i][j] = 0.0
# L
L = [e.copy() for e in A]
for i in range(n):
for j in range(n-1,i,-1):
L[i][j] = 0.0
L[i][i] = 1.0
return PZ, L, U
'''
https://nttdocomo-developers.jp/entry/2024/02/17/090000
スバラしき逆行列の世界
・LU分解 三角行列
'''
def lu_decomposition_with_partial_pivoting(mA, EPS=1.0e-7):
n = len(mA)
A = [e.copy() for e in mA]
L = [ [0 for _ in range(n)] for _ in range(n)]
U = [ [0 for _ in range(n)] for _ in range(n)]
P = [_ for _ in range(n)]
if n == 1:
L[0][0] = 1
U[0][0] = A[0][0]
return P, [[1]], [[A[0][0]]]
for i in range(n):
#
# pivot = np.argmax(np.abs(A[i:, i])) + i
#
pivot = i
pv = A[i][i]
for k in range(i,n):
if abs(A[k][i]) > pv:
pivot = k
pv = abs(A[k][i])
#--^^
if pivot != i:
# A[[i, pivot]] = A[[pivot, i]]
for k in range(n):
xa = A[pivot][k]
A[pivot][k] = A[i][k]
A[i][k] = xa
xx = P[pivot]
P[pivot] = P[i]
P[i] = xx
if i > 0:
# L[[i, pivot], :i] = L[[pivot, i], :i]
for k in range(i):
xl = L[pivot][k]
L[pivot][k] = L[i][k]
L[i][k] = xl
L[i][i] = 1
for j in range(i, n):
#
# (np.dot(L[i, :i], U[:i, j])
#
sum1 = 0
for k in range(i):
sum1 += L[i][k] * U[k][j]
#
# U[i, j] = A[i, j] - np.dot(L[i, :i], U[:i, j])
#
U[i][j] = A[i][j] - sum1
#if abs(U[i][i]) < EPS:
# return None, None, None
for j in range(i+1, n):
#
# np.dot(L[j, :i], U[:i, i])
#
sum2 = 0
for k in range(i):
sum2 += L[j][k] * U[k][i]
#
# L[j, i] = (A[j, i] - np.dot(L[j, :i], U[:i, i])) / U[i, i]
#
if abs(U[i][i]) < EPS:
return None, None, None
L[j][i] = (A[j][i] - sum2) / U[i][i]
return P, L, U
def matrix_dmp(msg, A):
print(msg, " MATRIX:")
n = len(A)
for i in range(n):
for j in range(n):
print(" % 0.4f" % (A[i][j]), end='')
print("")
def chk(a):
if type(a) == list:
if len(a) == 0:
return None
else:
if type(a[0]) != list:
A = [a.copy()]
else:
A = [e.copy() for e in a]
n = len(A)
m = len(A[0])
else:
n = 0
m = 0
if m != n or n == 0: # 正方行列のみ
return None
return A
if __name__ == '__main__':
import numpy as np
def permutation(P, mat):
'''
順列 交換回数計算
matrixをもとに戻す
'''
n = len(P)
Z = [e for e in P]
cnt = 0
for i in range(n):
if Z[i] != i:
min = i
for j in range(i+1,n):
if Z[j] < Z[min]:
min = j
for j in range(n):
xx = mat[min][j]
mat[min][j] = mat[i][j]
mat[i][j] = xx
xx = Z[min]
Z[min] = Z[i]
Z[i] = xx
cnt += 1
return cnt
def gen_matrix(n=0, RMAX=50, DCP=1):
'''
行列生成 N x N
n = 0 : ランダムNxN , 9 : 9 x 9行列
RMAX = 50 : (+-50)で要素データ、 99: (+-99)で要素データ
DCP = 1 : 要素データ * 10, +9 : 要素データ * (10**9) 、 -9 : 要素データ / (10**9)
'''
import random as r
DC = 10**abs(DCP)
if n == 0:
N = r.randrange(10,41) # 10x10 ~ 40x40の行列を作る
else:
N = n # n x n の行列を作る
nx = r.randrange(N*4) # 時々、対角優位行列でなくする
m = []
for i in range(N):
m.append([r.randrange(-RMAX,RMAX+1) for j in range(N)])
for i in range(N):
if i != nx:
ml = 0
for j in range(N):
if i != j:
ml += abs(m[i][j])
if m[i][i] < 0:
m[i][i] -= ml
else:
m[i][i] += ml
for i in range(N):
for j in range(N):
if DCP < 0:
m[i][j] /= DC
else:
m[i][j] *= DC
return m
def testMatrix(nc, EPS=1.0e-7):
for n in range(1, nc+1):
print("")
print("TEST MATRIX No.", n)
A = gen_matrix(RMAX=360, DCP=-3)
nn = len(A)
print(" %d x %d 行列" % (nn,nn))
print(" numpy RANK:", np.linalg.matrix_rank(A))
#P1, L1, U1 = lu_decomposition_with_partial_pivoting(A)
P1, L1, U1 = lu(A)
if L1 is None: # 左辺行列がない
print(" 計算できません")
else:
print("..検算:")
lxu = np.dot(L1,U1)
det = 1
for i in range(len(A)):
det *= U1[i][i]
s = permutation(P1, lxu)
if s & 1:
det = -det
ndet = np.linalg.det(A)
diff = abs(det-ndet)/abs(ndet)
if diff < EPS:
print(" det() OK")
else:
print(" det() ??NG")
print(" DET:",det)
print(" numpy det:",ndet)
if np.allclose(A, lxu):
print(" matrix OK")
else:
print(" matrix ??NG")
def test(msg,mat, EPS=1.0e-7):
print("\n",msg," ● ***Results***")
print("Used A ---")
print(mat)
print("**Answers**")
A = chk(mat)
if A is None:
print("計算できません")
return
print(" numpy RANK:", np.linalg.matrix_rank(A))
#P1, L1, U1 = lu_decomposition_with_partial_pivoting(A)
P1, L1, U1 = lu(A)
if L1 is None:
print(" 計算できません")
else:
matrix_dmp("L1:",L1)
matrix_dmp("U1:",U1)
lxu = np.dot(L1,U1)
print("行入れ替え情報:", P1)
det = 1
for i in range(len(A)):
det *= U1[i][i]
s = permutation(P1, lxu)
if s & 1:
det = -det
print("DET:",det)
if abs(det) < EPS:
print(" DET() == ZERO")
ndet = np.linalg.det(A)
print("numpy det:",ndet)
print("..検算..")
if np.allclose(det, ndet):
print(" det() OK")
else:
print(" det() ??NG")
if np.allclose(A, lxu):
print(" matrix OK")
else:
print(" matrix ??NG")
test("計算−1",[[2, 3, 1, -3],[-1, 2, 2, 4],[4, 1, -3, 5],[5, -4, -4, 1]])
test("計算−2",[[2,0],[0,5]])
test("計算−3",[ [0.0, 1.0],[1.0, 0.0] ])
test("計算−4",[[4]])
test("計算−5",[0.0])
test("計算−6",[[-1, 1, 3],[2, 3, -1],[3, 4, -2]])
test("計算−7",[[1, 3, 9],[-1, 1, -1],[2, -4, -2]])
test("計算−8",[[1,-1,-1],[-1,1,-1],[-1,-1,1]])
test("計算-9",[[-5, -1, 10, -10], [-9, 3, -9, -7], [9, -4, -10, 0], [-3, 7, 7, -9]])
test("計算−10",[[0,-2,0],[-1,5,2],[0,-1,1]])
test("計算−11",[[0,0,3],[-1,5,2],[0,-1,2]])
test("計算−12",[[1, 2, 2],[2, 1, 2],[2, 2, 1]])
test("計算−13",[ [0.0, -1.0, 1.0, 0.0, -1.0] ,[4.0, 4.0, 2.0, 1.0, 1.0] ,[4.0, 1.0, 1.0, 3.0, 2.0] ,[0.0, 3.0, -1.0, 4.0, -2.0] ,[-1.0, -1.0, -1.0, -1.0, -1.0] ])
print("\no o o o o o o")
testMatrix(5)
----
2024-07-08 「余因子展開逆行列計算」
参考:
初等線形代数ー考え方と応用プログラムー 石原辰雄、長谷川勝也 著 共立出版 1988
余因子展開で逆行列計算をやってみた。
$ python INV余因子展開.py
Input matrix is :
0.00000000 -2.00000000 0.00000000
-1.00000000 5.00000000 2.00000000
0.00000000 -1.00000000 1.00000000
The Adjoint is :
-3.50000000 -1.00000000 2.00000000
-0.50000000 -0.00000000 -0.00000000
-0.50000000 -0.00000000 1.00000000
検算 invert @ A:
1.00000000 0.00000000 0.00000000
0.00000000 1.00000000 0.00000000
0.00000000 0.00000000 1.00000000
numpy.inv:
-3.50000000 -1.00000000 2.00000000
-0.50000000 -0.00000000 -0.00000000
-0.50000000 0.00000000 1.00000000
--- INV余因子展開.py ---
def fdet(A, n):
'''
My行列式計算
'''
det = 0
if n == 1:
det = A[0][0]
elif n == 2:
det = A[0][0] * A[1][1] - A[0][1] * A[1][0]
else:
for x in range(n):
submatrix = [ e.copy() for e in A]
del submatrix[0]
[ e.pop(x) for e in submatrix]
det = det + (-1)**(x) * A[0][x] * fdet(submatrix, n-1)
del submatrix
return det
def cofactor(A, ia, ja):
'''
余因子展開 [0][0] [0][1] [0][2] ... [2][2] ....
0123 0123 0123 0123 0123
0 ABCD 0 .... 0 .... 0 .... 0 AB.D
1 EFGH 1 .FGH 1 E.GH 1 EF.H 1 EF.H
2 IJKL 2 .JKL 2 I.KL 2 IJ.L 2 ....
3 MNOP 3 .NOP 3 M.OP 3 MN.P 3 MN.P
余因子部 行列式計算
'''
n = len(A)
ny = n - 1
# 余因子展開
YY = [e.copy() for e in A]
del YY[ia]
[ e.pop(ja) for e in YY]
# determinant 余因子 行列式計算
cdet = fdet(YY, ny)
del YY
return cdet
def inv0(A):
'''
逆行列計算
Y:余因子行列(adjugate matrix)
det : 行列式計算結果
det = Y[0][0] * A[0][0] - (Y[1][0] * A[0][1]) + (Y[2][0] * A[0][2]) - ... + ... . . .
Y[i][j] = Y[i][j] / det (逆行列計算)
return {Y or None}
'''
n = len(A)
if n == 1:
det = A[0][0]
Y = [[1.0]]
else:
Y = [[0.0 for _ in range(n)] for _ in range(n)]
for i in range(n):
for j in range(n):
# Set cofactor determinat to adjugate matrix
Y[j][i] = cofactor(A, i, j)
# Calculate determinant
det = 0.0
for i in range(n):
if i & 1:
det -= (A[0][i] * Y[i][0])
else:
det += (A[0][i] * Y[i][0])
# Calculate end
if abs(det) < 0.000000001:
return None
# Calculate inverse matrix
# Matrix SIGN C0 C1 C2 C3 C4 . . .
# R0| + - + - + - + -
# R1| - + - + - + - +
# R2| + - + - + - + -
# | : : : : : : : :
# Rn(n-int(n/2)) == 0| + - + - + - + -
# Rn(n-int(n/2)) == 1| - + - + - + - +
#
for i in range(n):
for j in range(n):
if ((i & 1) + (j & 1)) & 1:
Y[i][j] = ((-1) * Y[i][j]) / det
else:
Y[i][j] = Y[i][j] / det
# Set inverse matrix
return Y
def display(A):
'''
行列 表示
'''
for i in range(N):
for j in range(N):
print("% 3.8f " % (A[i][j]), end="")
print()
if ( __name__ == '__main__' ):
import numpy as np
#A = [[5, -2, 2, 7], [1, 0, 0, 3], [-3, 1, 5, 0], [3, -1, -9, 4]]
#A = [[1, 3, 9],
# [-1, 1, -1],
# [2, -4, -2]] # 非正則
A = [
[0, -2, 0],
[-1, 5, 2],
[0, -1, 1]]
#A = [[-1, 1, 3],
# [2, 3, -1],
# [3, 4, -2]] # 非正則
#A = [[-6, -2, -9, -2], [-10, 3, -8, 11], [7, -9, -9, 5], [-11, 8, 5, 5]]
N = len(A)
print("Input matrix is :")
display(A)
print("\nThe Adjoint is :")
adj = inv0(A)
if adj == None:
print("逆行列ができません。")
exit()
display(adj)
print("検算 invert @ A:")
km = np.array(adj) @ A
display(km)
del km
del adj
print("numpy.inv:")
nui = np.linalg.inv(A)
display(nui)
del nui
2024-06-15 「HILL暗号復号キー」
HILL暗号の復号キーの作り方がわからなくて探してしまった。
以下例題。
---- hill_decode_key.py ---
'''
Hill暗号
暗号復号キーのテスト
参照:
https://github.com/krshrimali/Hill-Cipher
krshrimali/Hill-Cipher
'''
import numpy as np
def multi_inverse(b, n):
r1 = n
r2 = round(b,0)
t1 = 0
t2 = 1
inv_t = None
while(r1 > 0 and r2 != 0 ):
q = int(r1/r2)
r = r1 - q * r2
r1 = r2
r2 = r
t = t1 - q * t2
t1 = t2
t2 = t
if(r1 == 1):
inv_t = t1
break
return inv_t
''' 暗号文ダンプ '''
def dump_m(str,m):
print(str, end='')
print(" \"", end='')
for x in m:
for y in x:
print(chr(int(y)+0x20),end='')
print("\"")
for x in m:
for y in x:
print(" %d [%c]" % (int(y), int(y)+0x20), end='')
print('')
''' 暗号復号キー作成 (整数) '''
def gen_encode_key(key, mod):
n = len(key)
m = len(key[0])
det = np.linalg.det(key)
ekey = np.linalg.inv(key) * det * multi_inverse(det, mod) % mod
tm = ekey.tolist()
for i in range(n):
for j in range(m):
tm[i][j] = round(tm[i][j],0)
return np.array(tm)
# ******* Main ********
mn = 3 # 3行3列行列暗号キー
mod = 0x5B # 暗号電文コードであつかう法 0x20 - 0x7A
ss = 0x20 # 開始文字コード 空白
txt = [[19],[35],[51]] # 暗号文 "3CS" 3次列ベクトル
ks = (0x30 - 0x20) # 暗号キー 行列要素開始文字'0'
ke = (0x5A - 0x20) # 暗号キー 行列要素終了文字'Z'
n = 0
while True:
key_matrix = np.random.randint(ks,ke,(mn,mn)).tolist()
minv = multi_inverse(np.linalg.det(key_matrix), mod)
if minv == None:
continue
print(".... No. %d ...." % (n+1))
print(" KEY:",key_matrix)
for i in range(mn):
for j in range(mn):
print(chr(key_matrix[i][j]+ss), end='')
print('')
key_matrix_inv = gen_encode_key(key_matrix, mod)
print("key_inv:", key_matrix_inv.tolist())
p = np.array(key_matrix) @ txt % mod
dump_m("暗号変換:", p)
# 暗号復号
en = key_matrix_inv @ p % mod
dump_m("暗号復号:", en)
n += 1
if n >= 3:
break
......
実行。
$ python hill_decode_key.py
.... No. 1 ....
KEY: [[19, 17, 23], [44, 45, 23], [48, 55, 54]]
317
LM7
PWV
key_inv: [[54.0, 51.0, 21.0], [85.0, 52.0, 4.0], [39.0, 50.0, 43.0]]
暗号変換: "DCH"
36 [D]
35 [C]
40 [H]
暗号復号: "3CS"
19 [3]
35 [C]
51 [S]
.... No. 2 ....
KEY: [[44, 32, 41], [46, 26, 37], [42, 38, 22]]
L@I
N:E
JF6
key_inv: [[32.0, 77.0, 88.0], [51.0, 13.0, 32.0], [8.0, 87.0, 87.0]]
暗号変換: "K?a"
43 [K]
31 [?]
65 [a]
暗号復号: "3CS"
19 [3]
35 [C]
51 [S]
.... No. 3 ....
KEY: [[50, 29, 47], [33, 28, 30], [48, 54, 55]]
R=O
A<>
PVW
key_inv: [[45.0, 44.0, 12.0], [46.0, 52.0, 68.0], [38.0, 76.0, 75.0]]
暗号変換: "uKX"
85 [u]
43 [K]
56 [X]
暗号復号: "3CS"
19 [3]
35 [C]
51 [S]
2024-06-14 「Hill暗号」
検索で見つけたPDFに、行列計算で HILL暗号ができるとあったのでちょっとやってみた。
ものを知らないと時間がかかるなあ。
暗号キーは何でもいいとうわけではないようだ。復号キーを作るときに正しくできない場合がある。
キーの設定後、正しく復号できたかをチェックすること。
--- hill_2.py ----
'''
HILL暗号プログラム
参照:https://www.geeksforgeeks.org/hill-cipher/
Hill Cipher
http://axoluder.seesaa.net/article/310022099.html
ヒル暗号(暗号化・復号編)
”Cryptography in an algebraic alphabet” L.S.Hill, Amer. Math. Monthly, v. 36,1929, p. 306-31
"Applications of Linear Algebra Data Encryption" Scott Gregory MATH 308
'''
import numpy as np
''' KEY計算 '''
def gen_key(key):
from sympy import Matrix
i = len(key)
if 1 > i > 9:
return None,None
km = [[0 for i in range(3)] for j in range(3)]
for i in range(i):
if 0x20 <= ord(key[i]) < 0x7B:
km[i//3][i%3] = ord(key[i]) - 0x20
tmpk = Matrix(km)
return km, tmpk.inv_mod(0x5B).tolist()
''' 暗号文ダンプ '''
def dump_m(str,m):
print(str, end='')
print(" \"", end='')
for x in m:
for y in x:
print(chr(int(y)+0x20),end='')
print("\"")
for x in m:
for y in x:
print(" %02X [%c]" % (int(y), int(y)+0x20), end='')
print('')
print("# ********************")
print("# Hill暗号プログラム")
print("# ********************\n")
print("# 暗号キー設定")
key, inv_key = gen_key("PWBEWCXBO")
# 暗号変換キー表示
print(" 暗号キー:", key)
# 暗号復号キー表示
print("暗号復号キー:", inv_key)
KEY = np.array(key)
ENCODE = np.array(inv_key)
print("# 入力電文は、コード0x20~0x7B(空白、記号、A-Z,a-z)")
print("# 暗号キーが3次行列なので、電文は3行n列行列にして不足分は空白を埋める")
b = "Hi, It's awesome."
c = len(b)
n = c // 3
if n * 3 < c:
n += 1
#
# 暗号キーが3次行列なので、暗号文は3行
#
a = [[ 0 for i in range(n)] for j in range(3)]
for i in range(c):
if 0x20 <= ord(b[i]) < 0x7B:
a[i//n][i%n] = ord(b[i]) - 0x20
dump_m("入力電文:", a)
# 暗号変換
p = KEY @ a % 0x5B
dump_m("暗号変換:", p)
# 暗号復号
en = ENCODE @ p % 0x5B
dump_m("暗号復号:", en)
----
実行。
$ python hill_2.py
# ********************
# Hill暗号プログラム
# ********************
# 暗号キー設定
暗号キー: [[48, 55, 34], [37, 55, 35], [56, 34, 47]]
暗号復号キー: [[73, 2, 58], [13, 80, 53], [74, 23, 1]]
# 入力電文は、コード0x20~0x7B(空白、記号、A-Z,a-z)
# 暗号キーが3次行列なので、電文は3行n列行列にして不足分は空白を埋める
入力電文: "Hi, It's awesome. "
28 [H] 49 [i] 0C [,] 00 [ ] 29 [I] 54 [t]
07 ['] 53 [s] 00 [ ] 41 [a] 57 [w] 45 [e]
53 [s] 4F [o] 4D [m] 45 [e] 0E [.] 00 [ ]
暗号変換: "?1)&H!F5MkZn)c.txK"
1F [?] 11 [1] 09 [)] 06 [&] 28 [H] 01 [!]
26 [F] 15 [5] 2D [M] 4B [k] 3A [Z] 4E [n]
09 [)] 43 [c] 0E [.] 54 [t] 58 [x] 2B [K]
暗号復号: "Hi, It's awesome. "
28 [H] 49 [i] 0C [,] 00 [ ] 29 [I] 54 [t]
07 ['] 53 [s] 00 [ ] 41 [a] 57 [w] 45 [e]
53 [s] 4F [o] 4D [m] 45 [e] 0E [.] 00 [ ]
2024-07-31 「行列式計算」
逆行列計算で正則行列でなくても結果がでるので、行列式計算をやってみた。
ガウス・ジョルダン消去法での計算追加。
$ python det.py
**** TEST No.1 *****
入力: MATRIX:
[ ]
.
My det() 計算できません
.
gauss-jordan det() 計算できません
.
**** TEST No.2 *****
入力: MATRIX:
[ 3.00000 ]
.
my Det(): 3
.
gauss-jordan Det(): 3.0
.
numpy det(): 3.0000000000000004
numpy Rank(): 1
**** TEST No.3 *****
入力: MATRIX:
[ 0.00000 -2.00000 0.00000 ]
[ -1.00000 5.00000 2.00000 ]
[ 0.00000 -1.00000 1.00000 ]
.
my Det(): -2
.
gauss-jordan Det(): -2.0
.
numpy det(): -2.0
numpy Rank(): 3
**** TEST No.4 *****
入力: MATRIX:
[ 1.00000 -1.00000 -1.00000 ]
[ -1.00000 1.00000 -1.00000 ]
[ -1.00000 -1.00000 1.00000 ]
.
my Det(): -4
.
gauss-jordan Det(): -4.0
.
numpy det(): -4.0
numpy Rank(): 3
**** TEST No.5 *****
入力: MATRIX:
[ 7.00000 2.00000 -4.00000 2.00000 3.00000 ]
[ 1.00000 5.00000 2.00000 0.00000 3.00000 ]
[ -5.00000 -6.00000 3.00000 1.00000 2.00000 ]
[ 0.00000 2.00000 7.00000 4.00000 3.00000 ]
[ 4.00000 2.00000 -5.00000 -3.00000 5.00000 ]
.
my Det(): -2346
.
gauss-jordan Det(): -2346.0
.
numpy det(): -2345.999999999999
numpy Rank(): 5
**** TEST No.6 *****
入力: MATRIX:
[ 1.00000 0.00000 5.00000 ]
[ 3.00000 0.00000 -1.00000 ]
[ 4.00000 0.00000 2.00000 ]
.
my Det(): 0
.
gauss-jordan det() 計算できません
.
numpy det(): 0.0
numpy Rank(): 2
**** TEST No.7 *****
入力: MATRIX:
[ 1.00000 3.00000 9.00000 ]
[ -1.00000 1.00000 -1.00000 ]
[ 2.00000 -4.00000 -2.00000 ]
.
my Det(): 0
.
gauss-jordan det() 計算できません
.
numpy det(): 1.1102230246251546e-15
numpy Rank(): 2
**** TEST No.8 *****
入力: MATRIX:
[ -1.30000 1.60000 3.20000 ]
[ -4.60000 5.70000 -2.60000 ]
[ -1.20000 0.20000 6.30000 ]
.
my Det(): 22.94499999999999
.
gauss-jordan Det(): 22.944999999999993
.
numpy det(): 22.944999999999993
numpy Rank(): 3
......................
--- det.py -------
def determinant(mm):
'''
My行列式計算 正方行列制限、計算実行
'''
A = chk(mm)
if A is None:
return None
n = len(A)
return fdet(A, n)
def fdet(A, n):
'''
My行列式計算
'''
det = 0
if n == 1:
det = A[0][0]
elif n == 2:
det = A[0][0] * A[1][1] - A[0][1] * A[1][0]
else:
for x in range(n):
submatrix = [ e.copy() for e in A]
del submatrix[0]
[ e.pop(x) for e in submatrix]
det = det + (-1)**(x) * A[0][x] * fdet(submatrix, n-1)
return det
def gj_det(PA, E=1.0E-7):
'''
gauss-jordan 消去法で行列計算
参照:初等線形代数 --考え方と応用プログラム-- 石原辰雄 著 共立出版 1986,1988
DET.GJ2
'''
A = chk(PA)
if A is None:
return None
n = len(A)
det = 1.0
for i in range(n):
am = 0
ii = 0
for k in range(i,n):
ab = abs(A[k][i])
if ab > am:
am = ab
ii = k
if am < E:
return None
if i != ii:
det = -det
for j in range(i,n):
xx = A[i][j]
A[i][j] = A[ii][j]
A[ii][j] = xx
aii = A[i][i]
det *= aii
for j in range(n):
A[i][j] /= aii
for k in range(n):
if k != i:
ww = A[k][i]
for j in range(i,n):
A[k][j] -= ww * A[i][j]
return det
def gen_matrix():
'''
行列生成 N x N
'''
import random as r
N = r.randrange(3,7)
RMAX = 70
m = []
for i in range(N):
m.append([r.randrange(-RMAX,RMAX)/10 for j in range(N)])
return m
def matrix_dmp(msg, MAT):
'''
行列の印刷
'''
print(msg, " MATRIX:")
if MAT is None:
print(" 結果がありません")
return
if len(MAT) == 0:
A = [[]]
else:
if type(MAT[0]) == list:
A = [e.copy() for e in MAT]
else:
A = [MAT]
n = len(A)
nm = len(A[0])
for i in range(n):
print("[",end='')
if nm <= n:
for j in range(nm):
print(" % .5f" % (A[i][j]), end='')
else:
for j in range(n):
print(" % .5f" % (A[i][j]), end='')
print(" |",end='')
for j in range(n,nm):
print(" % .5f" % (A[i][j]), end='')
print(" ]")
def chk(m):
if type(m) == list:
if len(m) == 0:
return None
else:
if type(m[0]) != list:
A = [m.copy()]
else:
A = [e.copy() for e in m]
n = len(A)
m = len(A[0])
else:
n = 0
m = 0
if m != n: # 正方行列のみ
return None
return A
if __name__ == '__main__':
import numpy as np
t = 1
def test(m):
global t
print("**** TEST No.%d *****" % (t))
t += 1
matrix_dmp("入力:",m)
print(".")
det = determinant(m)
if det is None:
print("My det() 計算できません")
else:
print("my Det():", det)
print(".")
det = gj_det(m)
if det is None:
print("gauss-jordan det() 計算できません")
else:
print("gauss-jordan Det():", det)
print(".")
nm = chk(m)
if nm is not None:
print("numpy det():", np.linalg.det(nm))
print("numpy Rank():", np.linalg.matrix_rank(nm))
print("")
test([])
test([3])
test([[0,-2,0],[-1,5,2],[0,-1,1]])
test([[1,-1,-1],[-1,1,-1],[-1,-1,1]])
test([[7,2,-4,2,3],[1,5,2,0,3],[-5,-6,3,1,2],[0,2,7,4,3],[4,2,-5,-3,5]])
test([[1,0,5],[3,0,-1],[4,0,2]])
test([[1,3,9],[-1,1,-1],[2,-4,-2]])
test(gen_matrix())
---
参照:https://colab.research.google.com/github/colbrydi/MatrixAlgebra/blob/main/docs/_sources/09--Determinants_pre-class-assignment.ipynb#scrollTo=zzVEI_6JiHWG
09 Pre-Class Assignment: Determinants
2024-05-12 「Heirloom-doctools 色」
.CL green This
.CL red color
.CL blue
on print \X'SetColor:blue on green'\fBis Blue.\fP
.PS
box "\fBBOX\fP"
.PE
\X'SetColor:white on black'\fBFill Color is \X'SetColor:red on black'Gray\fP.
\X'SetColor:blue on yellow'Box line is NOT Green if box with \X'SetColor:white on black'\fBfill.
\fP\X'SetColor:'This color is black.
Allows colors on "color1 on color2" are
.br
\X'SetColor:1.0 0.2 0.5 rgb'red , green , blue , cyan , magenta , yellow , white , black.
-------------------------
$ pic color.pic |troff -ms -mcolor | dpost > Post.ps
2024-05-11 「Heirloom-doctools EQN」
(1) 数式名称
.EQ 表示位置 数式名称
表示位置:左寄せ、中央寄せ
数式名称:表示名称となる
表示:
x ** 2 + 2 x + 2 = 0 数式名称
troff -me .. : 「-me」がないと数式名称が表示されない。
漢字フォント切り替えをきちんとやらないと数式名称を指定してもゴミ数字1,2等が表示される。
\fJ日本語\fP abcd <<== 注意★
|x ** 2 + 2 x + 2 = 0 ★ 数式名称|
↑数字表示になる
(2) .nr 番号レジスタ
.nr 名前 初期値 加算値
名前:レジスタ名 1,2,3文字の名前
初期値: .nrは整数カウンタ。その初期値を設定する。
加算値: 呼び出し毎に加減算する値。
使用:
xxx\n+X : xxx9 表示。1文字レジスタ名のとき。
xxx\n+(XX : xxx9 表示。2文字レジスタ名のとき。
xxx\n+[XXX]: xxx9 表示。3文字レジスタ名のとき。
3文字名称を使う場合は、レジスタ定義前に、
.do xflag 3
を記述する。
$ troff -rNN=1 xxx.trof | dpost > xxx.ps
番号レジスタ定義と初期値を与える。
(3) Xバー表示
... EQN ...
.fp 0 J GenJyuuGothic-Monospace-Normal
.fp 0 JB GenJyuuGothic-Monospace-Bold
.ft CW
.EQ
delim $$
.EN
$x dot$
$x dotdot$
$x hat$
$x tilde$
$x vec$
$x dyad$
$x under$
$x bar$
\f(JBxバーがずれる。\fP\fJどうしても揃えるとき\fP
$pile { ~~ x} bar$
...
(4) .DS ~ .DE
DS定義をして EQ リクエストエラーになる場合は、DS定義前に".DS[改行].DE"を入れる。
\" ダミーEQ-EN
.EQ
.EN
.DS
; 以下 EQN 記述
2024-05-15 「heirloom-doctools」
参照:https://github.com/n-t-roff/heirloom-doctools/issues/85
Build problem #85
(1) Computing Science Technical Report No. 116
PIC — A Graphics Language for Typesetting User Manual / Brian W. Kernighan
AT&T Bell Laboratories
(2) Tbl — A Program to Format Tables / L. L. Cherry, M. E. Lesk / AT&T Bell Laboratories
(3) Heirloom Documentation Tools Nroff/Troff User’s Manual
Joseph F. Ossanna, Brian W. Kernighan, Gunnar Ritter, ...others
(4) Document Formatting and Typesetting on the UNIX System"
Second Edition Volume I (1987), II (1988) / Narain Gehani, Steven Lally / SILICON PRESS
(5) Font Handling in Troff With PostScript Devices
Gunnar Ritter 10 / 24 / 06
(6) https://github.com/arnoldrobbins/dformat
arnoldrobbins/dformat (データ構造印刷 AWK スクリプト)
(7) https://troff.org/prog.html
troff and its companion programs
(8) DFORMAT — A Program for Typesetting Data Formats / Jon L. Bentley / AT&T Bell Laboratories
行列計算をやったので数式を清書してみたいと思ってroff-eqn | tbl | pic | grap をまたやってみた。
Heirloom Doctools を使う。昔からの書き方が使えるので。
UTF-8日本語マニュアルが清書できるようになっていた。
$ git clone https://github.com/n-t-roff/heirloom-doctools.git
$ sudo apt install -y cmake
$ sudo apt install -y bison flex
$ sudo apt install -y byacc
$ YACC=/usr/bin/byacc
$ export YACC
$ cd heirloom-doctools
$ ./configure
$ make
$ sudo make install
....
dpost , grap等は /usr/local/ucb にある
$ ls /usr/local/ucb
addbib col eqn lookbib otf_info ptx soelim tbl
checkeq dhtml grap neqn pic refer sortbib troff
checknr dpost indxbib nroff picpack roffbib ta vgrind
(o)clear
$ make mrproper
(o)alias
$ nano ~/.bash_aliases
...
alias nroff='/usr/local/ucb/nroff'
alias troff='/usr/local/ucb/troff'
alias tbl='/usr/local/ucb/tbl'
alias eqn='/usr/local/ucb/eqn'
alias neqn='/usr/local/ucb/neqn'
alias dpost='/usr/local/ucb/dpost'
alias col='/usr/local/ucb/col'
alias grap='/usr/local/ucb/grap'
alias pic='/usr/local/ucb/pic'
...
$ . ~/..bash_aliases
aliasが登録される。
$ alias
コマンドで確認すること。
次回のログオンから自動登録される。
日本語manページダウンロード
https://linuxjm.sourceforge.io/download.html
マニュアルアーカイブのダウンロード
https://linuxjm.sourceforge.io/man-pages-ja-20231115.tar.gz
解凍。
man-pages-ja-20231115/manual/GNU_coreutils/man1/ls.1
を使う。
$ tbl -Tlocale ls.1 | neqn | nroff -Tlocale -mg -mandoc | col -x | ul
これで日本語マニュアルページが見える。
$ tbl -Tlocale ls.1 | neqn | nroff -Tlocale -mg -mandoc | col -bx > ls.txt
これで日本語マニュアルページのテキストになる。
$ nroff -ms -mandoc ls.1 | col -xb | paps --font="IPAMincho" > ls.ps
これで日本語マニュアルページのPostscriptファイルになる。
col -xb はバックスペースコードを削除する。
paps は sudo apt install paps でインストールする。
--font=desc
Use font based on description desc. Default is "Courier 10".
The format of the string representation is:
"[family-list] [style-options] [size]"
where family-list is a comma separated list of families option-
ally terminated by a comma, style-options is a whitespace sepa-
rated list of words where each word describes one of style,
variant, weight, or stretch, and size is a decimal number for
size in points, e.g. "Courier,Monospace Bold Italic 10".
指定がないとゴシック文字。フォントのファミリー名指定は、
fc-list より、フォント名称にある英文字IPAMincho等を指定する。
GRAP,PIC,EQN,TBLは、
$ /usr/local/ucb/grap FILE.grap| /usr/local/ucb/pic |/usr/local/ucb/tbl |/usr/local/ucb/eqn | /usr/local/ucb/troff -ms |/usr/local/ucb/dpost > FILE.ps
$ evince FILE.ps -> 印刷 PDF
で見える。
troff入力ファイル内にフォント割当をすると日本語が使える。
$ fc-list|grep -e ipa -e takao
---
/usr/share/fonts/opentype/ipafont-mincho/ipam.ttf: IPA明朝,IPAMincho:style=Regular
/usr/share/fonts/truetype/takao-mincho/TakaoPMincho.ttf: Takao P明朝,TakaoPMincho:style=Regular
/usr/share/fonts/opentype/ipafont-gothic/ipagp.ttf: IPA Pゴシック,IPAPGothic:style=Regular
/usr/share/fonts/opentype/ipafont-mincho/ipamp.ttf: IPA P明朝,IPAPMincho:style=Regular
/usr/share/fonts/opentype/ipafont-gothic/ipag.ttf: IPAゴシック,IPAGothic:style=Regular
/usr/share/fonts/truetype/takao-gothic/TakaoPGothic.ttf: Takao Pゴシック,TakaoPGothic:style=Regular
/usr/share/fonts/truetype/takao-gothic/TakaoGothic.ttf: Takaoゴシック,TakaoGothic:style=Regular
/usr/share/fonts/truetype/takao-mincho/TakaoMincho.ttf: Takao明朝,TakaoMincho:style=Regular
---
$ fc-list :lang=ja
日本語フォント一覧
troff ファイル
...
.fp 0 G TakaoMincho <<== ファイル名 ipam 等
.ft G
...で指定する。
$ TROFFONTS=/usr/share/fonts/truetype/takao-mincho
$ export TROFFONT
環境変数を設定する。
http://jikasei.me/font/genjyuu/
源柔ゴシック : genjyuugothic-20150607.7z (49.7 MB)
https://ftp.iij.ad.jp/pub/osdn.jp/users/8/8636/genjyuugothic-20150607.7z
解凍して、/usr/share/fonts/truetype/noto_jpを作成してコピーする。
$ sudo ls /usr/share/fonts/truetype/noto_jp
GenJyuuGothic-Bold.ttf GenJyuuGothic-Monospace-Regular.ttf
GenJyuuGothic-ExtraLight.ttf GenJyuuGothic-Normal.ttf
GenJyuuGothic-Heavy.ttf GenJyuuGothic-P-Bold.ttf
GenJyuuGothic-Light.ttf GenJyuuGothic-P-ExtraLight.ttf
GenJyuuGothic-Medium.ttf GenJyuuGothic-P-Heavy.ttf
GenJyuuGothic-Monospace-Bold.ttf GenJyuuGothic-P-Light.ttf
GenJyuuGothic-Monospace-ExtraLight.ttf GenJyuuGothic-P-Medium.ttf
GenJyuuGothic-Monospace-Heavy.ttf GenJyuuGothic-P-Normal.ttf
GenJyuuGothic-Monospace-Light.ttf GenJyuuGothic-P-Regular.ttf
GenJyuuGothic-Monospace-Medium.ttf GenJyuuGothic-Regular.ttf
GenJyuuGothic-Monospace-Normal.ttf
使う前にTROFFONTS環境変数にパス/usr/share/fonts/truetype/noto_jpを追加すること。
UTF-8漢字コードと半角英数字記号コードはフォント切り替えをしたほうがよい。
apt install *.ttcフォントから取り出した *.ttfは、表示されなかった。
データ構造印刷 AWK スクリプト arnoldrobbins/dformat は https://github.com/arnoldrobbins/dformat
から、git cloneするかプログラムをもらってくるかする。
解凍すると、dformat.awk, dformat の2つのAWKスクリプトが入っている。どちらかを使用する。
$ awk -f dformat < 構造定義テキスト > 構造定義.pic
----構造定義テキスト---
.begin dformat
style bitwid 0.09
Short
0 S
1-15 Integer
Int
0 S
1-31 Integer
Float
0 S
1-7 Exponent
8-31 Fraction
.end
---
$ pic 構造定義.pic | eqn | troff -ms | dpost > 構造定義.ps
eqn は,領域名称の右下小文字表示のために使用する。
$ evince 構造定義.ps
==========================
PIC boxの塗りつぶしの修正。
==========================
Boxの塗りつぶしが三角形にしかならないのでソースプログラムを修正した。
heirloom-doctools/pic/pltroff.c の関数 void box(double x0, double y0, double x1, double y1)
...
void box(double x0, double y0, double x1, double y1)
{
move(x0, y0);
//cont(x0, y1);
//cont(x1, y1);
//cont(x1, y0);
//cont(x0, y0);
cont(x1, y0);
cont(x1, y1);
cont(x0, y1);
cont(x0, y0);
}
...
2024-04-17 「固有値計算比較テスト」
参照:UNIXワークステーションによる科学技術計算ハンドブック 戸川隼人著 サイエンス社 1992
FORTRAN数値計算とプログラミング 国井利泰監修 中村明子、伊藤文子著 1971 共立出版
1.5 固有値 A.ヤコビ法 EX-1-5-A p-91 ~ 100
行列計算ソフトウェア 小国力編著 村田、三好、ドンガラ、長谷川著 丸善 1991,2000 プログラムFD付き
固有値計算と特異値計算 日本計算工学会編 長谷川,今村,山田,櫻井,荻田,相島,木村,中村著 丸善 2019
プログラムがダウンロード可。ヤコビ方式プログラムはV1.0、行列計算ソフトウェア(2000)のFDにあるものは
V2.0(サブルーチンの最後に検算が追加されている)となっている。
手順はThe Jacobi Method for Real Symmetric Matrices(H.Rutishauser)
となっている。下記のJohn Burkardt氏のものと同様である。
PYTHONに変換してやってみると検算で精度がわるい。John Burkardt氏と比べると判定値3箇所ほど違う
ところがある。John Burkardt氏のように変更するとよくなる。
https://people.sc.fsu.edu/~jburkardt/py_src/jacobi_eigenvalue/jacobi_eigenvalue.html
John Burkardt
テストする場合は、ここからjacobi_eigenvalue.pyをダウンロードすること。
people.math.sc.edu/Burkardt/py_src/jacobi_eigenvalue/jacobi_eigenvalue.htmlのもある
が更新日が古い、ライセンスがGPLとなっている。
新しいほうは、ライセンスがMIT。
http://ics.p.lodz.pl/~dpuchala/JacobiNewI.pdf
Handbook Series Linear Algebra/The Jacobi Method for Real Symmetric Matrices
H.Rutishauser
https://stackoverflow.com/questions/10806790/generating-symmetric-matrices-in-numpy
Generating Symmetric Matrices in Numpy
UNIXワークステーションによる科学技術計算ハンドブックのJAC7.CをPYTHONに変換したもの。
FORTRAN数値計算とプログラミングのFORTRANをPYTHONにしたもの。
J.Burkardt氏のものをそのまま使用。numpy.linalg.eig()を比べてみた。
ヤコビ法は、対称行列のみが計算対称なので対称行列のみを計算する。
$ python test-all.py
◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎
◎◎◎◎◎◎◎◎◎◎◎計算開始◎◎◎◎◎◎◎◎◎◎
◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎
No.1 計算行列 4 x 4
[[ 21.2 51.5 17.8 21.4 ]
[ 51.5 39. 56.05 -39.1 ]
[ 17.8 56.05 9. -44.75]
[ 21.4 -39.1 -44.75 -4.1 ]]
■■■■■■■■■ 計算結果 No.1 ■■■■(科学技術計算ハンドブック)■■■■■
固有値
[-40.00264901575932, 125.7493950044248, -58.50030558547468, 37.85355959680922]
固有ベクタ
[[ 0.21250619 0.36561209 -0.50821882 0.75025498]
[-0.58893811 0.69993445 0.39337504 0.09219412]
[ 0.75911892 0.51787123 0.28012443 -0.27762954]
[ 0.17813335 -0.3289817 0.71309186 0.5929077 ]]
■■■ 検証1 ■■■
[2.78043825e-14 4.81913530e-14 2.79740955e-14 1.57448258e-14]
■■■ 検証2 ■■■
[[ 0.00000000e+00 -7.10542736e-15 1.77635684e-14 -3.55271368e-15]
[-2.13162821e-14 4.26325641e-14 3.55271368e-15 5.77315973e-15]
[-1.77635684e-14 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 1.77635684e-15 2.13162821e-14 -2.13162821e-14 -1.42108547e-14]]
■■■■■■■■■ 計算結果 No.1 ■■■■(FORTRAN数値計算とプログラミング)■■■■■
固有値
[-55.792972180451464, -9.031737456399028, 64.02302580941523, 65.90168382743529]
固有ベクタ
[[ 0.62693309 0.38438309 0.59707089 -0.32048539]
[-0.74411862 0.24834997 0.34473792 -0.51552453]
[ 0.11869282 -0.85858514 0.17804532 -0.4658792 ]
[-0.19787469 -0.23109194 0.70211251 0.64380132]]
■■■ 検証1 ■■■
[39.42200601 39.964956 58.72369839 66.5872806 ]
■■■ 検証2 ■■■
[[ 7.82554737 4.18240917 10.38003546 -6.73857808]
[-23.86052837 -7.36359255 4.64960558 -53.92168093]
[-14.00308674 15.62161728 -11.26570479 -36.90058768]
[ 26.9711719 35.7973147 -56.49949274 -10.92046047]]
■■■■■■■■■ 計算結果 No.1 ■■■■(sc.fsu.edu/ j.burkardt)■■■■■
固有値
[-58.50030558547471, -40.002649015759324, 37.85355959680921, 125.74939500442483]
固有ベクタ
[[-0.50821882 0.21250619 0.75025498 0.36561209]
[ 0.39337504 -0.58893811 0.09219412 0.69993445]
[ 0.28012443 0.75911892 -0.27762954 0.51787123]
[ 0.71309186 0.17813335 0.5929077 -0.3289817 ]]
■■■ 検証1 ■■■
[8.70233572e-15 1.47555281e-14 1.23149709e-14 2.92964275e-14]
■■■ 検証2 ■■■
[[-3.55271368e-15 -1.77635684e-15 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 1.11022302e-14 0.00000000e+00]
[ 3.55271368e-15 1.42108547e-14 5.32907052e-15 -2.84217094e-14]
[ 7.10542736e-15 -3.55271368e-15 0.00000000e+00 -7.10542736e-15]]
■■■■■■■■■ 計算結果 No.1 ■■■■(PYTHON NUMPY linalg.eig)■■■■■
固有値
[125.74939500442478, 37.85355959680924, -58.50030558547472, -40.00264901575932]
固有ベクタ
[[-0.36561209 -0.75025498 -0.50821882 0.21250619]
[-0.69993445 -0.09219412 0.39337504 -0.58893811]
[-0.51787123 0.27762954 0.28012443 0.75911892]
[ 0.3289817 -0.5929077 0.71309186 0.17813335]]
■■■ 検証1 ■■■
[7.78360569e-14 3.52261012e-14 4.57735138e-14 1.83962314e-14]
■■■ 検証2 ■■■
[[ 2.84217094e-14 2.48689958e-14 -3.55271368e-15 -1.77635684e-15]
[-7.10542736e-14 2.04281037e-14 -3.55271368e-15 1.42108547e-14]
[ 1.42108547e-14 1.77635684e-15 -3.55271368e-14 1.06581410e-14]
[ 0.00000000e+00 1.42108547e-14 2.84217094e-14 -4.44089210e-15]]
◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎
◎◎◎◎◎◎◎◎◎◎◎計算開始◎◎◎◎◎◎◎◎◎◎
◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎◎
No.2 計算行列 4 x 4
[[-35.8 -61.45 6.5 -29.4 ]
[-61.45 97.2 58.1 20.7 ]
[ 6.5 58.1 26.6 -66.9 ]
[-29.4 20.7 -66.9 -7.9 ]]
■■■■■■■■■ 計算結果 No.2 ■■■■(科学技術計算ハンドブック)■■■■■
固有値
[-67.07620293659039, 144.65559681297157, 78.70918808502054, -76.18858196140172]
固有ベクタ
[[ 0.89518041 -0.27761022 0.32206096 -0.13364635]
[ 0.29515964 0.86519733 -0.21676487 -0.34253082]
[-0.00672204 0.41739515 0.64435728 0.6407338 ]
[ 0.33389765 -0.01214253 -0.65885766 0.67399666]]
■■■ 検証1 ■■■
[5.41051503e-14 1.82022411e-14 2.51214793e-14 2.77475809e-14]
■■■ 検証2 ■■■
[[ 4.97379915e-14 -7.10542736e-15 -1.06581410e-14 -1.06581410e-14]
[ 1.06581410e-14 -1.42108547e-14 1.77635684e-14 -2.13162821e-14]
[-1.50435220e-14 7.10542736e-15 -1.42108547e-14 -1.42108547e-14]
[ 1.06581410e-14 -5.32907052e-15 0.00000000e+00 0.00000000e+00]]
■■■■■■■■■ 計算結果 No.2 ■■■■(FORTRAN数値計算とプログラミング)■■■■■
固有値
[-68.61745588275613, 67.46200861910354, -1.1203217022646799, 82.37576896591735]
固有ベクタ
[[ 0.90198654 -0.42919041 0.02345202 0.04081524]
[ 0.34596093 0.68635341 0.26675139 -0.58144108]
[-0.23780854 -0.49630771 0.73918869 -0.38823425]
[ 0.10088817 0.31367698 0.61797555 0.71381689]]
■■■ 検証1 ■■■
[11.37656598 57.89211363 99.13680835 81.48374029]
■■■ 検証2 ■■■
[[ 3.82973654 -10.30545643 -30.5689359 7.39644255]
[ -9.78900249 24.44215811 80.52491271 -18.90791372]
[ -3.42970011 36.38253546 -5.20132185 -59.6167138 ]
[ 2.67805134 36.38937221 -48.80913453 -51.70329586]]
■■■■■■■■■ 計算結果 No.2 ■■■■(sc.fsu.edu/ j.burkardt)■■■■■
固有値
[-76.18858196140172, -67.07620293659033, 78.7091880850205, 144.65559681297154]
固有ベクタ
[[-0.13364635 0.89518041 0.32206096 -0.27761022]
[-0.34253082 0.29515964 -0.21676487 0.86519733]
[ 0.6407338 -0.00672204 0.64435728 0.41739515]
[ 0.67399666 0.33389765 -0.65885766 -0.01214253]]
■■■ 検証1 ■■■
[2.16831986e-14 1.21801131e-14 3.25611587e-14 4.28010775e-14]
■■■ 検証2 ■■■
[[ 1.24344979e-14 -7.10542736e-15 1.42108547e-14 -7.10542736e-15]
[-1.06581410e-14 0.00000000e+00 0.00000000e+00 2.84217094e-14]
[-1.42108547e-14 6.88338275e-15 7.10542736e-15 -2.84217094e-14]
[ 0.00000000e+00 7.10542736e-15 -2.84217094e-14 -1.28785871e-14]]
■■■■■■■■■ 計算結果 No.2 ■■■■(PYTHON NUMPY linalg.eig)■■■■■
固有値
[144.65559681297142, 78.70918808502046, -67.07620293659025, -76.18858196140174]
固有ベクタ
[[-0.27761022 0.32206096 0.89518041 -0.13364635]
[ 0.86519733 -0.21676487 0.29515964 -0.34253082]
[ 0.41739515 0.64435728 -0.00672204 0.6407338 ]
[-0.01214253 -0.65885766 0.33389765 0.67399666]]
■■■ 検証1 ■■■
[1.42978968e-13 7.58652039e-14 1.10133467e-13 3.46731022e-14]
■■■ 検証2 ■■■
[[ 1.42108547e-14 3.55271368e-14 -9.23705556e-14 5.32907052e-15]
[ 1.27897692e-13 -2.84217094e-14 -5.32907052e-14 1.77635684e-14]
[ 5.68434189e-14 5.68434189e-14 -2.53685961e-14 2.84217094e-14]
[ 2.55351296e-14 -2.13162821e-14 -1.06581410e-14 -7.10542736e-15]]
[test-all.tgz 2.8kb]
2024-04-10 「行列 dot()計算」
配列の内積計算。
---- mydot.py ------
def dim(a):
if not type(a) == list:
return []
return [len(a)] + dim(a[0])
def isnotnum(n):
return (not isinstance(n, int) and not isinstance(n, float) and not isinstance(n, complex))
def mydot(a,b):
''' Dot()
in: a, b : matrix (list)
out: matrix (list)
1
+-------+
n * m ==> 1 | n * m |
+-------+
b_col b_col
+-----+ +-------+
n * bl | B | ==> bl | n * B |
+-----+ +-------+
a_col a_col
+------+ +-------+
al | A | * n ==> al | A * n |
+------+ +-------+
a_col b_col b_col
+------+ +-----+ +-----+
al | A | * bl | B | ==> al | ans |
+------+ +-----+ +-----+
IF a_col != bl THEN ERROR
(A[0][0-n] * B[0-n][0])合計 ==> ans[0][0]
(A[0][0-n] * B[0-n][1])合計 ==> ans[0][1]
(A[0][0-n] * B[0-n][n])合計 ==> ans[0][n]
(A[1][0-n] * B[0-n][0])合計 ==> ans[1][0]
(A[1][0-n] * B[0-n][1])合計 ==> ans[1][1]
(A[1][0-n] * B[0-n][n])合計 ==> ans[1][n]
(A[n][0-n] * B[0-n][0])合計 ==> ans[n][0]
(A[n][0-n] * B[0-n][n])合計 ==> ans[n][n]
'''
alc = dim(a)
blc = dim(b)
rr = []
if len(alc) < 0 or len(alc) > 2:
return rr
if len(alc) == 1:
alc[0:0] = [1]
a = [a]
if len(blc) < 0 or len(blc) > 2:
return rr
if len(blc) == 1:
blc[0:0] = [1]
b = [b]
if len(alc) == 0:
if isnotnum(a):
return rr
if len(blc) == 0:
if isnotnum(b):
return []
return [[a*b]]
rr = [el.copy() for el in b]
for i in range(blc[0]):
for j in range(blc[1]):
if isnotnum(rr[i][j]):
return []
rr[i][j] = a * rr[i][j]
return rr
if len(blc) == 0:
if isnotnum(b):
return []
rr = [el.copy() for el in a]
for i in range(alc[0]):
for j in range(alc[1]):
if isnotnum(rr[i][j]):
return []
rr[i][j] = b * rr[i][j]
return rr
if alc[1] != blc[0]: # if a columns != b lines then error
return rr
for i in range(alc[0]): # 0 ~ (alines - 1)
wc = [0 for j in range(blc[1])] # b columns as ans line
ae = a[i]
for j in range(blc[1]):
be = [e[j] for e in b] # b.T
for k in range(len(be)):
if isnotnum(a[i][k]):
return []
if isnotnum(be[k]):
return []
wc[j] += (a[i][k] * be[k])
rr.append(wc)
return rr
if ( __name__ == '__main__' ):
a = [[1,2],[3,4]]
b = [[10,20],[30,40]]
print("a=",a)
print("b=",b)
print(mydot(a,b))
a = [1,2,3]
b = [[100,200,300],[400,500,600],[700,800,900]]
print("a=",a)
print("b=",b)
print(mydot(a,b))
b = 3
a = [[100,200,300],[400,500,600],[700,800,900]]
print("a=",a)
print("b=",b)
print(mydot(a,b))
a = 0.5
b = [[100,200,300],[400,500,600],[700,800,900]]
print("a=",a)
print("b=",b)
print(mydot(a,b))
a = 3
b = 20
print("a=",a)
print("b=",b)
print(mydot(a,b))
a = [3]
b = [20]
print("a=",a)
print("b=",b)
print(mydot(a,b))
a = [[3]]
b = [[20]]
print("a=",a)
print("b=",b)
print(mydot(a,b))
---
$ python mydot.py
...
a= [[1, 2], [3, 4]]
b= [[10, 20], [30, 40]]
[[70, 100], [150, 220]]
a= [1, 2, 3]
b= [[100, 200, 300], [400, 500, 600], [700, 800, 900]]
[[3000, 3600, 4200]]
a= [[100, 200, 300], [400, 500, 600], [700, 800, 900]]
b= 3
[[300, 600, 900], [1200, 1500, 1800], [2100, 2400, 2700]]
a= 0.5
b= [[100, 200, 300], [400, 500, 600], [700, 800, 900]]
[[50.0, 100.0, 150.0], [200.0, 250.0, 300.0], [350.0, 400.0, 450.0]]
a= 3
b= 20
[[60]]
a= [3]
b= [20]
[[60]]
a= [[3]]
b= [[20]]
[[60]]
2024-04-10 「行列 四則演算」
行列の四則演算。
掛算は単純な掛算。dot(),@ とは違う。
>>> import numpy as np
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[10,20],[30,40]])
>>> a+b
array([[11, 22],
[33, 44]])
>>> a-b
array([[ -9, -18],
[-27, -36]])
>>> a*b
array([[ 10, 40],
[ 90, 160]])
>>> a/b
array([[0.1, 0.1],
[0.1, 0.1]])
>>> np.dot(a,b)
array([[ 70, 100],
[150, 220]])
>>> a@b
array([[ 70, 100],
[150, 220]])
---- mycalc_matrix.py -----
def dim(a):
if not type(a) == list:
return []
return [len(a)] + dim(a[0])
def isnotnum(n):
return (not isinstance(n, int) and not isinstance(n, float) and not isinstance(n, complex))
def mycalc(func, x,y):
if func == "+":
return x + y
elif func == "-":
return x - y
elif func == "*":
return x * y
elif func == "/":
if y == 0:
return None
else:
return x / y
else:
return None
def mycalc_matrix(func, a,b):
''' mycalc_matrix()
in: a, b : matrix (list), numeric
out: matrix (list)
a_col {+} b_col {a_col} or {b_col}
+------+ {-} +-----+ {al}+-----+
al | A | {*} bl | B | ==> or | ans |
+------+ {/} +-----+ {bl}+-----+
IF al == a_col == 1 THEN OK
IF bl == b_col == 1 THEN OK
IF al == 1 and a_col == b_col THEN OK
IF bl == 1 and a_col == b_col THEN OK
IF a_col == 1 and al == bl THEN OK
IF b_col == 1 and al == bl THEN OK
IF a_col == b_col and al == bl THEN OK
'''
alc = dim(a)
blc = dim(b)
rr = []
if len(alc) < 0 or len(alc) > 2:
return rr
if len(alc) == 0:
alc = [1,1]
a = [[a]]
if len(alc) == 1:
alc[0:0] = [1]
a = [a]
if len(blc) < 0 or len(blc) > 2:
return rr
if len(blc) == 0:
blc = [1,1]
b = [[b]]
if len(blc) == 1:
blc[0:0] = [1]
b = [b]
if mycalc(func,1,1) == None: # chack func
return rr
for i in range(alc[0]):
for j in range(alc[1]):
if isnotnum(a[i][j]):
return []
for i in range(blc[0]):
for j in range(blc[1]):
if isnotnum(b[i][j]):
return []
if alc[0] == alc[1] == 1:
rr = [el.copy() for el in b]
for i in range(blc[0]):
for j in range(blc[1]):
rr[i][j] = mycalc(func,a[0][0],rr[i][j])
elif blc[0] == blc[1] == 1:
rr = [el.copy() for el in a]
for i in range(alc[0]):
for j in range(alc[1]):
rr[i][j] = mycalc(func,rr[i][j],b[0][0])
elif alc[0] == 1 and alc[1] == blc[1]:
rr = [[mycalc(func,a[0][j],el[j]) for j in range(blc[1])] for el in b]
elif blc[0] == 1 and alc[1] == blc[1]:
rr = [[mycalc(func,el[j],b[0][j]) for j in range(alc[1])] for el in a]
elif alc[1] == 1 and alc[0] == blc[0]:
for i in range(alc[0]):
rr.append([mycalc(func,a[i][0],b[i][j]) for j in range(blc[1])])
elif blc[1] == 1 and alc[0] == blc[0]:
for i in range(alc[0]):
rr.append([mycalc(func,a[i][j],b[i][0]) for j in range(alc[1])])
elif alc[1] == blc[1] and alc[0] == blc[0]:
for i in range(alc[0]):
rr.append([mycalc(func,a[i][j],b[i][j]) for j in range(alc[1])])
# else Error
return rr
if ( __name__ == '__main__' ):
a = [[1,2,3],[4,5,6],[7,8,9]]
b = [[100,200,300],[400,500,600],[700,800,900]]
print("a=",a)
print("b=",b)
print("add", mycalc_matrix("+",a,b))
print("sub", mycalc_matrix("-",a,b))
print("mul", mycalc_matrix("*",a,b))
print("div", mycalc_matrix("/",b,a))
a = 1000
print("a=",a)
print("b=",b)
print("add", mycalc_matrix("+",a,b))
print("sub", mycalc_matrix("-",a,b))
print("mul", mycalc_matrix("*",a,b))
print("div", mycalc_matrix("/",a,b))
b = [[1,2,3],[4,5,6],[7,8,9]]
a = [[100,200,300]]
print("a=",a)
print("b=",b)
print("add", mycalc_matrix("+",a,b))
print("sub", mycalc_matrix("-",a,b))
print("mul", mycalc_matrix("*",a,b))
print("div", mycalc_matrix("/",a,b))
b = [[1,2,3],[4,5,6],[7,8,9]]
a = [[100],[400],[700]]
print("a=",a)
print("b=",b)
print("add", mycalc_matrix("+",a,b))
print("sub", mycalc_matrix("-",a,b))
print("mul", mycalc_matrix("*",a,b))
print("div", mycalc_matrix("/",a,b))
b = 2
a = [[100],[400],[700]]
print("a=",a)
print("b=",b)
print("add", mycalc_matrix("+",a,b))
print("sub", mycalc_matrix("-",a,b))
print("mul", mycalc_matrix("*",a,b))
print("div", mycalc_matrix("/",a,b))
-----
$ python mycalc_matrix.py
..
a= [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
b= [[100, 200, 300], [400, 500, 600], [700, 800, 900]]
add [[101, 202, 303], [404, 505, 606], [707, 808, 909]]
sub [[-99, -198, -297], [-396, -495, -594], [-693, -792, -891]]
mul [[100, 400, 900], [1600, 2500, 3600], [4900, 6400, 8100]]
div [[100.0, 100.0, 100.0], [100.0, 100.0, 100.0], [100.0, 100.0, 100.0]]
a= 1000
b= [[100, 200, 300], [400, 500, 600], [700, 800, 900]]
add [[1100, 1200, 1300], [1400, 1500, 1600], [1700, 1800, 1900]]
sub [[900, 800, 700], [600, 500, 400], [300, 200, 100]]
mul [[100000, 200000, 300000], [400000, 500000, 600000], [700000, 800000, 900000]]
div [[10.0, 5.0, 3.3333333333333335], [2.5, 2.0, 1.6666666666666667], [1.4285714285714286, 1.25, 1.1111111111111112]]
a= [[100, 200, 300]]
b= [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
add [[101, 202, 303], [104, 205, 306], [107, 208, 309]]
sub [[99, 198, 297], [96, 195, 294], [93, 192, 291]]
mul [[100, 400, 900], [400, 1000, 1800], [700, 1600, 2700]]
div [[100.0, 100.0, 100.0], [25.0, 40.0, 50.0], [14.285714285714286, 25.0, 33.333333333333336]]
a= [[100], [400], [700]]
b= [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
add [[101, 102, 103], [404, 405, 406], [707, 708, 709]]
sub [[99, 98, 97], [396, 395, 394], [693, 692, 691]]
mul [[100, 200, 300], [1600, 2000, 2400], [4900, 5600, 6300]]
div [[100.0, 50.0, 33.333333333333336], [100.0, 80.0, 66.66666666666667], [100.0, 87.5, 77.77777777777777]]
a= [[100], [400], [700]]
b= 2
add [[102], [402], [702]]
sub [[98], [398], [698]]
mul [[200], [800], [1400]]
div [[50.0], [200.0], [350.0]]
2024-04-07 「非対称行列固有値計算」
計算対称行列に合わない固有値計算関数の使い方でどうなるかをやってみた。
$ python lib_jacob.py
■■■■■■■■■ 入力 ■■■■■■■■■
MATRIX: [[1, 7, 3], [2, 9, 12], [5, 22, 7]]
対称行列ではありません。
■■■■■■■ ヤコビ法計算 ■■■■■■■
EPS= 2.220446049250313e-16
KOUT= 9
AMAX= 0.000000000000000
固有値: [[-4.784566014866619, 0.0, -1.1036075382276867e-29], [0.0, -0.41221518263870705, 1.726327615835052e-18], [-1.1036075382276867e-29, 1.726327615835052e-18, 22.196781197505327]]
固有ベクタ: [[0.7992781967609033, 0.5119293149747735, 0.31477411051752296], [-0.5684930090684294, 0.47424576916171074, 0.6722400234087083], [0.19485908452766953, -0.7162536749655646, 0.6700825398974086]]
■■■■■■■■■ 計算結果 ■■■■■■■■■
LAMDA(1)= -4.7845660148666189215305167
LAMDA(2)= -0.4122151826387070450152805
LAMDA(3)= 22.1967811975053272988134268
X(0)= 0.799278196760903 0.511929314974773 0.314774110517523
X(1)= -0.568493009068429 0.474245769161711 0.672240023408708
X(2)= 0.194859084527670 -0.716253674965565 0.670082539897409
計算行列= [[ 1 7 3]
[ 2 9 12]
[ 5 22 7]]
固有値= [[-4.78456601 0. 0. ]
[ 0. -0.41221518 0. ]
[ 0. 0. 22.1967812 ]]
固有ベクタ= [[ 0.7992782 0.51192931 0.31477411]
[-0.56849301 0.47424577 0.67224002]
[ 0.19485908 -0.71625367 0.67008254]]
■■■ 検証方法1 ■■■
[7.43850938 8.50221312 6.18347139]
■■■ 検証方法2 ■■■
検算 dot(計算行列 , 固有ベクトルの1列)ー(固有値1*固有ベクトルの1列)
[ 1.22860368 -3.899564 -6.21412547]
検算 dot(計算行列 , 固有ベクトルの2列)ー(固有値2*固有ベクトルの2列)
[ 1.89391371 -3.10748224 7.68402713]
検算 dot(計算行列 , 固有ベクトルの3列)ー(固有値3*固有ベクトルの3列)
[ 0.04372984 -0.2008658 6.18005332]
■■■ 検証方法3 ■■■
[[ 1.22860368 1.89391371 0.04372984]
[-3.899564 -3.10748224 -0.2008658 ]
[-6.21412547 7.68402713 6.18005332]]
. . .
■■■■■■ numpy.linalg.eig()計算 ■■■■■■
■■■■■■■■■ 計算結果 ■■■■■■■■■
LAMDA(1)= 25.5548386342907107859900862
LAMDA(2)= -0.5789337929080543565518724
LAMDA(3)= -7.9759048413826647561108985
X(0)= -0.260976503318146 -0.973445274559594 0.189104107807029
X(1)= -0.587027077498621 0.228061283850043 -0.581572782101413
X(2)= -0.766348794609388 -0.019807782467165 0.791209665973142
計算行列= [[ 1 7 3]
[ 2 9 12]
[ 5 22 7]]
固有値= [[25.55483863 0. 0. ]
[ 0. -0.57893379 0. ]
[ 0. 0. -7.97590484]]
固有ベクタ= [[-0.2609765 -0.97344527 0.18910411]
[-0.58702708 0.22806128 -0.58157278]
[-0.76634879 -0.01980778 0.79120967]]
■■■ 検証方法1 ■■■
[1.28094913e-14 2.21849431e-15 3.55964581e-15]
■■■ 検証方法2 ■■■
検算 dot(計算行列 , 固有ベクトルの1列)ー(固有値1*固有ベクトルの1列)
[ 0.00000000e+00 -7.10542736e-15 -1.06581410e-14]
検算 dot(計算行列 , 固有ベクトルの2列)ー(固有値2*固有ベクトルの2列)
[ 1.55431223e-15 1.58206781e-15 -5.37764278e-17]
検算 dot(計算行列 , 固有ベクトルの3列)ー(固有値3*固有ベクトルの3列)
[-3.33066907e-15 8.88178420e-16 -8.88178420e-16]
■■■ 検証方法3 ■■■
[[ 0.00000000e+00 1.55431223e-15 -3.33066907e-15]
[-7.10542736e-15 1.58206781e-15 8.88178420e-16]
[-1.06581410e-14 -5.37764278e-17 -8.88178420e-16]]
---- lib_jacob.py ----
"""
固有値 ヤコビ法計算
"""
import sys
import math
import numpy as np
def chk_symmetric(mat, n):
for i in range(n):
for j in range(n):
if mat[i][j] != mat[j][i]:
return 0
return 1
def calc_jacob(mat,n,eps,cmax):
'''
ヤコビ法で計算
入力引数:計算マトリクス(実対象行列)、次数、収束値、計算回数
戻り値:固有値・マトリクス、固有ベクトル・マトリクス、計算回数、収束値
参照:FORTRAN数値計算とプログラミング
国井利泰監修 中村明子、伊藤文子著 1971 共立出版
1.5 固有値 A.ヤコビ法 EX-1-5-A p-91 ~ 100
より、Fortranの手順をPythonに修正したもの。
'''
u = [[ 0.0 for i in range(n)] for j in range(n)]
for i in range(n):
u[i][i] = 1.0
n1 = n-1
kout = 0
while True:
amax = 0.0
for i in range(n1):
i1 = i+1
for j in range(i1,n):
w = math.fabs(mat[i][j])
if amax < w:
amax = w
k=i
l=j
if eps >= amax:
break
if kout >= cmax:
break
kout = kout + 1
a1 = mat[k][k]
a2 = mat[l][l]
a3 = mat[k][l]
w = (a1-a2) * 0.5
if w < 0.0:
af = a3
else:
af = -1.0 * a3
if w == 0.0:
z = math.sqrt(4.0*math.pow(a3,2))
t = 2.0*af / z
else:
w = af/w
t = w/(math.sqrt(w*w+1.0)+1.0)
zz = t*t+1.0
c = math.sqrt(1.0/zz)
s = t * c
for i in range(n):
aw = u[i][k]
az = u[i][l]
u[i][k] = aw*c + az*s
u[i][l] = -aw*s + az*c
if i ==k:
continue
if i == l:
continue
aw = mat[i][k]
az = mat[i][l]
mat[i][k] = aw*c + az*s
mat[i][l] = -aw*s + az*c
mat[k][i] = mat[i][k]
mat[l][i] = mat[i][l]
asc2 = 2.0 * a3 * s * c
mat[k][k] = a1 * math.pow(c,2) + a2 * math.pow(s,2) + asc2
mat[l][l] = a1 * math.pow(s,2) + a2 * math.pow(c,2) - asc2
mat[k][l] = 0.0
mat[l][k] = 0.0
return [mat, u, kout, amax]
def input_matrix():
'''
計算終了判定値:実数
マトリックスの入力
次数n:1〜10
マトリクスデータ:N*N実数対称行列
戻り値:計算終了判定値・実数、次数n、計算対称行列N*N
'''
while True:
inn = None
try:
inn = input("収束判定値は")
eps = float(inn)
break
except:
if inn == None:
return [0.0,0,None]
continue
while True:
inn = None
try:
inn = input("行列入力:実対象行列n x n の次数:整数n:")
n = int(inn)
if 0 < n <= 10:
print ("n:",n," eps:",eps)
break
except:
if inn == None:
return [0.0,0,None]
continue
mat = [[ 0.0 for i in range(n)] for j in range(n)]
print("行列入力:実数 x n個[ENTER] n回")
for i in range(n):
for j in range(n):
while True:
inn = None
try:
print("%d x %d 番目の実数入力:" % (i+1,j+1), end='')
inn = input("")
mat[i][j] = float(inn)
break
except:
if inn == None:
return [0.0,0,None]
continue
return [eps, n, mat]
def matrix():
eps = 2.2204460492503131E-016
n = 3
mat = [
[1, 7, 3],
[2, 9, 12],
[5, 22, 7]]
return [eps,n,mat]
def matrix2():
eps = 2.2204460492503131E-016
n = 3
mat = [
[1, -1, -1],
[-1, 1, -1],
[-1, -1, 1]]
return [eps,n,mat]
def matrix3():
eps = 2.2204460492503131E-016
n = 4
mat = [
[89, 75, 22, 102],
[75, 116, 27, 120],
[22,27, 33, 62],
[102,120,62,200]]
return [eps,n,mat]
def eig_check(A, value, vector):
r = np.zeros(value.shape[0])
i = 0
for l, v in zip(value, vector.T):
r[i] = np.linalg.norm(A.dot(v) - l*v)
i += 1
return r
def result(A, evalue, evect):
print("■■■■■■■■■ 計算結果 ■■■■■■■■■")
n = len(A)
for i in range(n):
print(" LAMDA(%d)= % 20.25f" % (i+1, evalue[i][i]))
for i in range(n):
print(" X(%d)=" % (i), end='')
for j in range(n):
print("% 20.15f " % (evect[i][j]), end='')
print("")
print("計算行列=",A)
print("固有値=",evalue)
print("固有ベクタ=",evect)
print(" ■■■ 検証方法1 ■■■")
print(eig_check(A, np.array([evalue[i][i] for i in range(n)]), evect))
print(" ■■■ 検証方法2 ■■■")
for i in range(n):
print("検算 dot(計算行列 , 固有ベクトルの%d列)ー(固有値%d*固有ベクトルの%d列)" % (i+1,i+1,i+1) )
print(np.dot(A,evect[:,i])-evalue[i][i]*evect[:,i])
print(" ■■■ 検証方法3 ■■■")
print(np.dot(A,evect)-np.dot(evect,evalue))
if ( __name__ == '__main__' ):
import warnings
warnings.filterwarnings('ignore')
m_max = 50
eps,n,mat = matrix()
if n > 0:
print("■■■■■■■■■ 入力 ■■■■■■■■■")
print("MATRIX:",mat)
if chk_symmetric(mat, n) == 0:
print("対称行列ではありません。")
# sys.exit()
np_inmatrix = np.array([e.copy() for e in mat]) # copy matrix
print("■■■■■■■ ヤコビ法計算 ■■■■■■■")
egvalue, egvect, kout, amax = calc_jacob(mat,n,eps,m_max)
print(" EPS=",eps)
print(" KOUT=",kout)
print(" AMAX=% 20.15f" % (amax))
print(" 固有値:",egvalue)
print(" 固有ベクタ:",egvect)
np_vector = np.array(egvect)
for i in range(n):
v = egvalue[i][i]
egvalue[i] = [0.0 for j in range(n)]
egvalue[i][i] = v
np_evalue = np.array(egvalue)
result(np_inmatrix, np_evalue, np_vector)
print(". . .")
print("■■■■■■ numpy.linalg.eig()計算 ■■■■■■")
egvalue, egvect = np.linalg.eig(np_inmatrix)
np_value = np.array([[0.0 for j in range(n)] for j in range(n)])
for i in range(n):
np_value[i][i] = egvalue[i]
result(np_inmatrix, np_value, egvect)
print("")
---
2024-04-05 「行列 固有値計算検算」
★Mathematica
参照:https://mathematica.stackexchange.com/questions/268772/check-eigenvalues-and-eigenvectors-are-correct
Check Eigenvalues and Eigenvectors are correct [closed]
https://ss1.xrea.com/penguinitis.g1.xrea.com/computer/programming/Python/eigenvalue.html
行列の固有値の計算 (検証方法あり )
https://jp.mathworks.com/help/matlab/ref/eig.html
eig 固有値と固有ベクトル
In[42]:=
mat={{1.0,-1.0,-1.0},{-1.0,1.0,-1.0},{-1.0,-1.0,1.0}}
Out[42]= {{1.,-1.,-1.},{-1.,1.,-1.},{-1.,-1.,1.}}
In[43]:=
{e,v}=Eigensystem[mat]
Out[43]= {{2.,2.,-0.999999999999999},
{{-0.408248290463863,-0.408248290463863,0.816496580927726},
{0.707106781186548,-0.707106781186548,0.},
{-0.577350269189626,-0.577350269189626,-0.577350269189626}}}
In[44]:=
mat.v[[1]]==e[[1]] v[[1]]
Out[44]= True
In[45]:=
mat.v[[2]]==e[[2]] v[[2]]
Out[45]= False
In[46]:=
mat.v[[3]]==e[[3]] v[[3]]
Out[46]= True
In[47]:=
mat.v[[1]]-(e[[1]] v[[1]])
Out[47]= {-3.33066907387547*10^-16,-3.33066907387547*10^-16,-4.44089209850063*10^-16}
In[49]:=
mat.v[[2]]-(e[[2]] v[[2]])
Out[49]= {0.,-2.22044604925031*10^-16,-1.11022302462516*10^-16}
In[50]:=
mat.v[[3]]-(e[[3]] v[[3]])
Out[50]= {6.66133814775094*10^-16,1.33226762955019*10^-15,3.33066907387547*10^-16}
★OCTAVE
>> a = [1 -1 -1; -1 1 -1; -1 -1 1];
>> [v,e] = eig(a)
v =
0.577350 -0.396780 -0.713605
0.577350 0.816390 0.013181
0.577350 -0.419610 0.700424
e =
Diagonal Matrix
-1 0 0
0 2 0
0 0 2
>> a*v(:,1) <<== 計算行列値 * 固有値ベクトルの1列目
ans =
-0.5774
-0.5774
-0.5774
>> e(1,1)*v(:,1) <<== 固有値1番目 * 固有値ベクトルの1列目
ans =
-0.5774
-0.5774
-0.5774
>> a*v(:,1) - e(1,1)*v(:,1)
ans = <<== 検算(計算行列値 * 固有ベクトルの1列目)ー(固有値1番目 * 固有ベクトルの1列目)
-1.1102e-16
-1.1102e-16
5.5511e-16
>> a*v(:,2) - e(2,2)*v(:,2)
ans = <<== 検算(計算行列値 * 固有ベクトルの2列目)ー(固有値2番目 * 固有ベクトルの2列目)
1.1102e-16
1.1102e-15
1.1102e-16
>> a*v(:,3) - e(3,3)*v(:,3)
ans = <<== 検算(計算行列値 * 固有ベクトルの3列目)ー(固有値3番目 * 固有ベクトルの3列目)
0
9.7145e-17
0
★PYTHON
---- mydot.py --------
import numpy as np
def mydot(A,val):
vd = np.array([0.0 for i in range(len(val))])
for i in range(len(A)):
for x,y in zip(A[i],val):
vd[i] += x*y
return vd
mat=np.array([[1,-1,-1],[-1,1,-1],[-1,-1,1]])
print("計算行列\n",mat)
e,v=np.linalg.eig(mat)
print("e=",e)
print("v=",v)
print("検算 dot(計算行列,固有ベクトルの1列)ー(固有値1*固有ベクトルの1列)")
print(mydot(mat,v[:,0])-e[0]*v[:,0])
print("検算 dot(計算行列,固有ベクトルの2列)ー(固有値2*固有ベクトルの2列)")
print(mydot(mat,v[:,1])-e[1]*v[:,1])
print("検算 dot(計算行列,固有ベクトルの3列)ー(固有値3*固有ベクトルの3列)")
print(mydot(mat,v[:,2])-e[2]*v[:,2])
print("")
print((mat.dot(v[:,0]))-e[0]*v[:,0])
print((mat.dot(v[:,1]))-e[1]*v[:,1])
print((mat.dot(v[:,2]))-e[2]*v[:,2])
---
$ python mydot.py
...
計算行列
[[ 1 -1 -1]
[-1 1 -1]
[-1 -1 1]]
e= [-1. 2. 2.]
v= [[-0.57735027 -0.57842803 0.57891179]
[-0.57735027 -0.20985087 -0.78809991]
[-0.57735027 0.7882789 0.20918812]]
検算 dot(計算行列,固有ベクトルの1列)ー(固有値1*固有ベクトルの1列)
[ 5.55111512e-16 -1.11022302e-16 -1.11022302e-16]
検算 dot(計算行列,固有ベクトルの2列)ー(固有値2*固有ベクトルの2列)
[ 0.00000000e+00 -5.55111512e-17 0.00000000e+00]
検算 dot(計算行列,固有ベクトルの3列)ー(固有値3*固有ベクトルの3列)
[ 2.22044605e-16 -4.44089210e-16 5.55111512e-17]
[ 5.55111512e-16 -1.11022302e-16 -1.11022302e-16]
[ 0.00000000e+00 -5.55111512e-17 0.00000000e+00]
[ 2.22044605e-16 -4.44089210e-16 5.55111512e-17]
...
>>> import numpy as np
>>> a = np.array([[1,-1,-1],[-1,1,-1],[-1,-1,1]])
>>> d,v = np.linalg.eig(a)
>>> d
array([-1., 2., 2.])
>>> v
array([[-0.57735027, -0.57842803, 0.57891179],
[-0.57735027, -0.20985087, -0.78809991],
[-0.57735027, 0.7882789 , 0.20918812]])
>>> dd = np.array([[d[0],0,0],[0,d[1],0],[0,0,d[2]]])
>>> dd
array([[-1., 0., 0.],
[ 0., 2., 0.],
[ 0., 0., 2.]])
>>> np.dot(a,v)
array([[ 0.57735027, -1.15685606, 1.15782358],
[ 0.57735027, -0.41970174, -1.57619982],
[ 0.57735027, 1.5765578 , 0.41837624]])
>>> np.dot(v,dd)
array([[ 0.57735027, -1.15685606, 1.15782358],
[ 0.57735027, -0.41970174, -1.57619982],
[ 0.57735027, 1.5765578 , 0.41837624]])
>>> np.dot(a,v)-np.dot(v,dd)
array([[ 5.55111512e-16, 0.00000000e+00, 2.22044605e-16],
[-1.11022302e-16, -5.55111512e-17, -4.44089210e-16],
[-1.11022302e-16, 0.00000000e+00, 5.55111512e-17]])
2024-03-31 「行列 固有値計算」
参照:東京大学のデータサイエンティスト育成講座
Pythonで手を動かして学ぶデータ分析 塚本邦尊、山田典一、大澤文孝 著 マイナビ出版2022
Chapter 2-3 Scipyの基礎 p-45,46
固有値 -1, 2, 2 固有ベクトル 0.577, -0.816, 0.428
0.577, 0.408, -0.816
0.577, 0.408, 0.389
SCIPYの固有値、固有ベクトル 計算をしたとき違う値が表示されたのが気になり調べてみた。
とりあえずは他のプログラム
---python-----
>>> import numpy as np
>>> mat = np.array([[1,-1,-1],[-1,1,-1],[-1,-1,1]])
>>> mat
array([[ 1, -1, -1],
[-1, 1, -1],
[-1, -1, 1]])
>>> evalue,evector = np.linalg.eig(mat)
>>> evalue
array([-1., 2., 2.])
>>> evector
array([[-0.57735027, -0.57842803, 0.57891179],
[-0.57735027, -0.20985087, -0.78809991],
[-0.57735027, 0.7882789 , 0.20918812]])
>>> import scipy
>>> evalue,evector = scipy.linalg.eig(mat)
>>> evalue
array([-1.+0.j, 2.+0.j, 2.+0.j])
>>> evector
array([[-0.57735027, -0.57842803, 0.57891179],
[-0.57735027, -0.20985087, -0.78809991],
[-0.57735027, 0.7882789 , 0.20918812]])
lapackのdgeevの結果と同様になる。
LAPACK/BLAS入門より
https://github.com/tkouya/lapack_blas_tutorial
dpkg -l liblapack-dev
dpkg -l libblas-dev
arm64 version 3.11.0-2
$ ./lapack_dgeev
A =
0: 1 -1 -1
1: -1 1 -1
2: -1 -1 1
A(org) =
0: 1 -1 -1
1: -1 1 -1
2: -1 -1 1
実数 実数 実数
Eigenvalues =
0: ( -1, 0)
1: ( 2, 0)
2: ( 2, 0)
(-0.57735, 0) (-0.578428, 0) (0.578912, 0)
(-0.57735, 0) (-0.209851, 0) (-0.7881, 0)
(-0.57735, 0) (0.788279, 0) (0.209188, 0)
||A * right_ev - lambda * right_ev||_F / ||A||_F = 2.55056138285437054e-16
||A^T * left_ev - lambda * left_ev||_F / ||A||_F = 4.84641987789776181e-16
.......
lapack_dgeev.cは修正して使わしてもらいました。
... lapack_dgeev.c ....
;;
//printf("Dim = "); scanf("%d", &dim);
dim = 3;
;;
↓ /*
for(i = 0; i < dim; i++)
{
for(j = 0; j < dim; j++)
{
// A = Lotkin matrix
//if(i == 0) ma[j] = 1.0;
//else ma[i * dim + j] = 1.0 / (double)(i + j + 1);
コメント // A = Random matrix
ma[i * dim + j] = (double)rand() / (double)RAND_MAX;
// ma_org = ma
ma_org[i * dim + j] = ma[i * dim + j] + 0.0 * I;
}
}
↑ */
ma_org[0 * dim + 0] = (ma[0 * dim + 0] = 1.0) + 0.0 * I;
ma_org[0 * dim + 1] = (ma[0 * dim + 1] = -1.0) + 0.0 * I;
ma_org[0 * dim + 2] = (ma[0 * dim + 2] = -1.0) + 0.0 * I;
ma_org[1 * dim + 0] = (ma[1 * dim + 0] = -1.0) + 0.0 * I;
ma_org[1 * dim + 1] = (ma[1 * dim + 1] = 1.0) + 0.0 * I;
ma_org[1 * dim + 2] = (ma[1 * dim + 2] = -1.0) + 0.0 * I;
ma_org[2 * dim + 0] = (ma[2 * dim + 0] = -1.0) + 0.0 * I;
ma_org[2 * dim + 1] = (ma[2 * dim + 1] = -1.0) + 0.0 * I;
ma_org[2 * dim + 2] = (ma[2 * dim + 2] = 1.0) + 0.0 * I;
;;
maの表示。
;;
// 固有値が実数の時
if(im_eig[i] == 0.0)
{
printf("実数 ");
for(j = 0; j < dim; j++)
;;
// 固有値が複素数になる場合
else if(im_eig[i] > 0.0)
{
printf("複素数 ");
for(j = 0; j < dim; j++)
;;
else
{
printf("その他 ");
for(j = 0; j < dim; j++)
;;
....
他のプログラムも同様。
$ ./lapack_ssyev
INPUT: A =
0: 1 -1 -1
1: -1 1 -1
2: -1 -1 1
OUTPUT: A =
0: -0.57735 -0.750394 -0.321832
1: -0.57735 0.0964827 0.810776
2: -0.57735 0.653911 -0.488944
Eigenvalues =
0: -1
1: 2
2: 2
absmax_eig = 2.0000000e+00
absmin_eig = -1.0000000e+00
cond2 = 2.0000000e+00
||ev^T * A * ev - lambda * I||_2 = 1.5325554e-07
$ ./lapack_dsyev
A =
0: 1 -1 -1
1: -1 1 -1
2: -1 -1 1
Envenvectors:
0: 0.57735 -0.39678 -0.713605
1: 0.57735 0.81639 0.0131811
2: 0.57735 -0.41961 0.700424
Eigenvalues =
0: -1
1: 2
2: 2
absmax_eig = 2.00000000000000000e+00
absmin_eig = -1.00000000000000022e+00
cond2 = 1.99999999999999956e+00
||ev^T * A * ev - lambda||_F / ||A||_F = 3.5090480e-16
・・・・・・
---- mathematica -----------------------
In[1]:= mat={{1.0,-1.0,-1.0},{-1.0,1.0,-1.0},{-1.0,-1.0,1.0}}
Out[1]= {{1.,-1.,-1.},{-1.,1.,-1.},{-1.,-1.,1.}}
In[2]:= MatrixForm[%]
Out[2]//MatrixForm= (1. -1. -1.
-1. 1. -1.
-1. -1. 1.
)
In[3]:= Eigenvalues[mat]
Out[3]= {2.,2.,-1.}
In[4]:= Eigenvectors[mat]
Out[4]= {{-0.408248290463863,-0.408248290463863,0.816496580927726},
{0.707106781186548,-0.707106781186548,0.},
{-0.577350269189626,-0.577350269189626,-0.577350269189626}}
In[5]:= Eigensystem[mat]
Out[5]= {{2.,2.,-0.999999999999999},
{{-0.408248290463863,-0.408248290463863,0.816496580927726},
{0.707106781186548,-0.707106781186548,0.},
{-0.577350269189626,-0.577350269189626,-0.577350269189626}}}
---SCILAB-------------
--> a = [ 1 -1 -1; -1 1 -1; -1 -1 1]
a =
1. -1. -1.
-1. 1. -1.
-1. -1. 1.
--> [t2, aa2] = spec(a)
t2 =
0.5773503 -0.3967799 -0.7136052
0.5773503 0.8163902 0.0131811
0.5773503 -0.4196102 0.7004241
aa2 =
-1. 0. 0.
0. 2. 0.
0. 0. 2.
--> A=[1,-1,-1;-1,1,-1;-1,-1,1]
A =
1. -1. -1.
-1. 1. -1.
-1. -1. 1.
--> [V,E]=bdiag(A)
V =
-1. 0. 0.
0. 2. 0.
0. 0. 2.
E =
0.5773503 0.4896217 0.6010959
0.5773503 0.3210539 -0.7850266
0.5773503 -0.8106756 0.1839307
----OCTAVE--------------------------
>> a = [1 -1 -1; -1 1 -1; -1 -1 1];
>> [v,d] = eig(a)
v =
0.577350 -0.396780 -0.713605
0.577350 0.816390 0.013181
0.577350 -0.419610 0.700424
d =
Diagonal Matrix
-1 0 0
0 2 0
0 0 2
-----JULIA-----------
julia> using LinearAlgebra
julia> A = [1 -1 -1;-1 1 -1; -1 -1 1]
3×3 Matrix{Int64}:
1 -1 -1
-1 1 -1
-1 -1 1
julia> eigvecs(A)
3×3 Matrix{Float64}:
-0.57735 0.707107 -0.408248
-0.57735 -0.707107 -0.408248
-0.57735 0.0 0.816497
julia> eigvals(A)
3-element Vector{Float64}:
-1.0000000000000002
2.0
2.0
他にも、手元にあったプログラムの手順でやってみた。
! 参照:FORTRAN数値計算とプログラミング
! 国井利泰監修 中村明子、伊藤文子著 1971 共立出版
! 1.5 固有値 A.ヤコビ法 EX-1-5-A p-91 ~ 100
FORTRANのプログラムでそれをfortran90に修正している。
gfortran でコンパイルした。
...
行列入力:実対象行列n x n の次数:整数n
3
実対象行列 N x N、 収束判定値EPS, 計算繰り返し回数Max Loop
N= 3, EPS:0.22204460492503E-15 ,Max Loop= 50
行列入力:実数 x n個[ENTER] n回
1 -1 -1
-1 1 -1
-1 -1 1
◇◇◇◇◇ 入力結果 ◇◇◇◇◇
A( 1)= 1.0000 -1.0000 -1.0000
A( 2)= -1.0000 1.0000 -1.0000
A( 3)= -1.0000 -1.0000 1.0000
・・・・・
U( 1)= 1.0000 0.0000 0.0000
U( 2)= 0.0000 1.0000 0.0000
U( 3)= 0.0000 0.0000 1.0000
◆◆◆◆◆ 計算結果 ◆◆◆◆◆◆
LAMDA( 1)= -0.9999999961338617
LAMDA( 2)= 1.9999999754758784
LAMDA( 3)= 1.9999999994888948
X( 1)= 0.5773502689056838 -0.8158338288228492 -0.0328909540699514
X( 2)= 0.5773502623183976 0.4364013294067319 -0.6900873411458593
X( 3)= 0.5773502588272095 0.3794325175124923 0.7229783123361159
KOUT= 5
AMAX= 0.000000000000000
...
となった。
結果を計算しないと正しいかどうかわからないというのが最近わかった。
2024-03-23 「RaspiでVisual Studio Codeデバッグ」
Visual Studio Code でデバッグ。
参照:https://code.visualstudio.com/docs/cpp/config-linux
Using C++ on Linux in VS Code
(1) mkdir ソースプログラムディレクトリ
(2) プログラム作成
$ cd ソースプログラムディレクトリ
$ nano sin.c
---
#include <stdio.h>
#include <math.h>
int main(int argc, char *argv[])
{
double n = 999.0;
if ( argc <= 1 ) {
printf("ラジアンを指定して?\n");
return 1;
}
sscanf(argv[1],"%lf",&n);
if ( fabs(n) > 2.0 ) {
printf("2ラジアンまで?\n");
return 1;
}
printf("結果: sin(%lf) = %lf\n",n, sin(n));
return 0;
}
---
(3) Visual Studio Codeインストール
$ sudo apt install code
(4) Visual Studio Code 起動
メニュー・ファイル・フォルダを開く 選択
"ソースプログラムディレクトリ"を開く
プログラム sin.c を開く。
(5) task.json自動作成
メニュー・ターミナル・規定のビルドタスクの構成 選択
選択リストのなかの"GCCアクティブなファイルのビルド"を選択する。
task.jsonが自動生成されて表示される。
cソースを選択して、
メニュー・実行・デバッグの実行 を選んで実行する。
エラーが出て終わる。
ディレクトリ ".vscode" 作成され、tasks.jsonができる。
(6) tasks.json修正
---
{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc アクティブなファイルのビルド",
"command": "/usr/bin/gcc",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}", # <<== ”,”追加
"-lm" # <<== リンクオブジェクト指定
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "コンパイラ: /usr/bin/gcc"
}
]
}
---
修正したら、保存する。
(7) プログラムのデバッグ
codeのメニュー・実行・デバッグの実行 => 最初のメニューを選んで実行する。
デバッグができるようになる。
このままでは、codeのメニュー・実行・デバッグなしの実行 でもデバッグとなってしまう。
(8) launch.json作成
codeのメニュー・実行・構成の追加 選択。
launch.jsonの編集ウィンドウになる。
「構成の追加」(青色ボタン)でGDB起動を選ぶ。
---
{
// IntelliSense を使用して利用可能な属性を学べます。
// 既存の属性の説明をホバーして表示します。
// 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) 起動",
"type": "cppdbg",
"request": "launch",
//"program": "プログラム名を入力してください (例: ${workspaceFolder}/a.out)",
"program": "${fileDirname}/${fileBasenameNoExtension}",
// プログラム名を入力してくださいを↑のように修正する。
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "gdb の再フォーマットを有効にする",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "逆アセンブリ フレーバーを Intel に設定",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}
---
修正したら、保存。
保存しなくてプログラムデバッグ・実行しても以前の状態で実行される。ここで保存される。
もう一度デバッグ・実行すると反映されている結果となる。
jsonファイルの修正はどちらも同じなので修正したら保存する。
(9) プログラムのデバッグなしで実行
codeのメニュー・実行・デバッグなしで実行、選択。
デバッグなしで実行される。
(10) プログラムに引数がある場合は、launch.jsonを修正する。
---
;; 途中の
"name": "(gdb) 起動",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": ["0.5"], <<== コマンド > プログラム名 引数(これを指定)
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
;;
---
修正したら、保存。
(11) ソースプログラムの修正
ソースプログラムを修正する。
(12) コンパイル
codeのメニュー・ターミナル・ビルドタスクの実行 選択
エラーの確認。修正。
2024-03-21 「juliaインストール、実行」
参照:https://www.jstage.jst.go.jp/article/itej/71/1/71_74/_pdf
動的プログラミング言語Juliaの紹介
(1)ダウンロード
https://julialang.org/downloads/
Current stable release: v1.10.2 (March 1, 2024)
Generic Linux on ARM [help] AArch64 (GPG)
julia-1.10.2-linux-aarch64.tar.gz
(2)インストール
ダウンロードし、解凍。
(3)実行
$ cd julia-1.10.2/bin
$ ./julia
☆JULIAからPython呼び出し。
・・・
julia> using Pkg
julia> Pkg.add("PyCall")
メッセージがでる。1回設定せればよい。
julia> using PyCall
julia> @pyimport numpy as np
julia> @pyimport scipy.linalg as linalg
julia> mat = np.array([[1,-1,-1],[-1,1,-1],[-1,-1,1]])
3×3 Matrix{Int64}:
1 -1 -1
-1 1 -1
-1 -1 1
julia> evalue,evector = linalg.eig(mat)
(ComplexF64[-0.9999999999999999 + 0.0im, 2.0 + 0.0im, 1.9999999999999996 + 0.0im],
[-0.5773502691896256 -0.5784280301128795 0.5789117904251897;
-0.5773502691896258 -0.20985087099025507 -0.7880999106986186;
-0.5773502691896258 0.7882789011031346 0.209188120273429])
ここまでPYTHONパッケージ。
以下、JULIAパッケージ。
julia> using LinearAlgebra
julia> A = [1 -1 -1;-1 1 -1; -1 -1 1]
3×3 Matrix{Int64}:
1 -1 -1
-1 1 -1
-1 -1 1
julia> eigvecs(A)
3×3 Matrix{Float64}:
-0.57735 0.707107 -0.408248
-0.57735 -0.707107 -0.408248
-0.57735 0.0 0.816497
julia> eigvals(A)
3-element Vector{Float64}:
-1.0000000000000002
2.0
2.0
----
☆ユーザ作成PYTHONプログラム呼び出し
・・・
julia> using PyCall
julia> scriptdir = @__DIR__
カレントディレクトリ、または、
julia> scriptdir = "/home/xxxxxx/xxx/sample"
julia> pushfirst!(PyVector(pyimport("sys")."path"), scriptdir)
julia> mytest = pyimport("sample")
julia> led24 = mytest.init_led(4)
julia> mytest.buzz(led24,600,2)
julia> mytest.led_close(led24)
-----sample.py-----------------
from gpiozero import LED
import time
def init_led(p):
''' p : pi number '''
return LED(p)
def led(led,s):
''' LED ON/OFF
led : pyobject led, s : 0 - off / 1 - ON '''
if s == 0:
led.off()
else:
led.on()
def led_close(led):
''' led object close
led " pyobject led '''
led.close()
def buzz(led,hz,t):
''' LED PWM 50% Output
led : pyobject led, hz : frequency 0-1200 , t : time (sec [float]) '''
if hz <= 0:
led.on()
else:
if hz > 1200:
hz = 1200;
onoff = 0.5 / hz
led.blink(onoff, onoff) # バックグラウンドでblinkは継続しない
time.sleep(t)
led.off()
if __name__ == '__main__':
ld4 = init_led(4)
buzz(ld4,400,1)
led_close(ld4)
...
☆bash 呼び出し。
・・・
julia> ”;”文字入力で。
shell> に変わる。bashコマンド実行できる。
戻るには、CTRL+C。
julia> になる。
2024-03-20 「マシンイプシロン」
$ cc epsilon.c -o eps-c
$ ./eps-c
LONG epsilon: 1.92592994438723585305597794258e-34
1.0 epsilon: 2.22044604925031e-16
0.0 epsilon: 4.94065645841247e-324
0.005 epsilon: 4.33680868994202e-19
1000.0 epsilon: 1.13686837721616e-13
$ cat epsilon.c
#include <stdio.h>
int main()
{
long double e, se;
double le, sle;
e = 1.0;
le = 1.0;
for (; 1.0 + (e /= 2.0L) != 1.0;) {
se = e;
}
printf("LONG epsilon: %.30Lg \n",se);
for (; 1.0 + (le /= 2.0) != 1.0; ) {
sle = le;
}
printf(" 1.0 epsilon: %.15g \n",sle);
le = 1.0;
for (; 0.0 + (le /= 2.0) != 0.0; ) {
sle = le;
}
printf(" 0.0 epsilon: %.15g \n",sle);
le = 1.0;
for (; 0.005 + (le /= 2.0) != 0.005; ) {
sle = le;
}
printf(" 0.005 epsilon: %.15g \n",sle);
le = 1.0;
for (; 1000.0 + (le /= 2.0) != 1000.0; ) {
sle = le;
}
le = 1.0;
printf(" 1000.0 epsilon: %.15g \n",sle);
return 0;
}
...
-----PYTHON---------------
>>> import numpy as np
>>> print(np.finfo(float).eps)
2.220446049250313e-16
>>> print(np.finfo(np.float32).eps)
1.1920929e-07
...
-------
参照:http://ri2t.kyushu-u.ac.jp/~watanabe/RESERCH/MANUSCRIPT/KOHO/CONVERGE/converge.pdf
いつ反復計算をやめるべきか? - ∼収束判定基準の設定方法
$ gfortran epsilon.f90 -o epsilon
$ ./epsilon
real(kind=4): 1.19209290E-07
real(kind=8): 2.2204460492503131E-016
real(kind=16): 1.92592994438723585305597794258492732E-0034
real: 1.19209290E-07
double precision: 2.2204460492503131E-016
----epsilon.f90-----------
program machine_epsilon
implicit none
real(kind=4) :: x
real(kind=8) :: y
real(kind=16) :: z
real :: x1
double precision :: y1
print *," real(kind=4):", epsilon(x)
print *," real(kind=8):", epsilon(y)
print *," real(kind=16):", epsilon(z)
print *," real:", epsilon(x1)
print *,"double precision:", epsilon(y1)
end program machine_epsilon
◆◆◆julia◆◆◆
参照:https://julialang.org/downloads/
Current stable release: v1.10.2 (March 1, 2024)
Generic Linux on ARM [help] AArch64 (GPG)
julia-1.10.2-linux-aarch64.tar.gz
Linux 6.6.20+rpt-rpi-2712 #1 SMP PREEMPT Debian 1:6.6.20-1+rpt1 (2024-03-07) aarch64 GNU/Linux
...
ダウンロードし、解凍。
$ cd julia-1.10.2/bin
$ ./julia
....
julia> Sys.WORD_SIZE
64
julia> eps()
2.220446049250313e-16
julia> eps(Float32)
1.1920929f-7
julia> eps(Float64)
2.220446049250313e-16
julia> eps(0.0)
5.0e-324
julia> eps(1.0)
2.220446049250313e-16
julia> eps(1000.)
1.1368683772161603e-13
julia> eps(0.005)
8.673617379884035e-19
julia> eps(0.1)
1.3877787807814457e-17
2024-03-10 「IEEE754 丸め」
参考:
http://verifiedby.me/kv/kv-intro.pdf
精度保証付き数値計算と kv ライブラリ
柏木 雅英 著
https://catalog.lib.kyushu-u.ac.jp/opac_download_md/1470409/p063.pdf
IEEE754と数値計算 : 浮動小数点演算の特徴とは?
皆本晃弥 著
https://www.am.ics.keio.ac.jp/proj/asap/wiki/?plugin=attach&refer=Numerical%20Recipe%20in%20C&openfile=ukiwa08.pdf
浮動小数点輪講
よしみ まさと 著
インターフェース2024/4月号 数学100の0.1を100回足す結果をみてEXCELとLibreOffice Calcを比べて
結果が微妙に違っている。丸め方がちょっと違うかもしれない?
そんなのもあって、以前も丸めをやってはいたが、ちょっと考えが甘かったのでもう一度。
近接偶数丸めのテストはどうするんだろうかと考えてみた。
もう少しわかりやすく改修しました。
......仮数部 LSB 1、小数点以下なし...(+n) + (+x)...............
...............................................
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1 0000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0010 0000 0000 .0
.
2305843009213690112
+) 256
------------------------------- この計算値は値の大小を確認するため。
2305843009213690368
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1111 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 1111 0000 .0
.
2305843009213690112
+) 240
-------------------------------------------------
2305843009213690368
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1110 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 1110 0000 .0
.
2305843009213690112
+) 224
-------------------------------------------------
2305843009213690368
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1101 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 1101 0000 .0
.
2305843009213690112
+) 208
-------------------------------------------------
2305843009213690368
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1100 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 1100 0000 .0
.
2305843009213690112
+) 192
-------------------------------------------------
2305843009213690368
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1011 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 1011 0000 .0
.
2305843009213690112
+) 176
-------------------------------------------------
2305843009213690368
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1010 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 1010 0000 .0
.
2305843009213690112
+) 160
-------------------------------------------------
2305843009213690368
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1001 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 1001 0000 .0
.
2305843009213690112
+) 144
-------------------------------------------------
2305843009213690368
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 1000 0000 .0
.
2305843009213690112
+) 128
-------------------------------------------------
2305843009213690368
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 111 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0111 0000 .0
.
2305843009213690112
+) 112
-------------------------------------------------
2305843009213690112
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 110 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0110 0000 .0
.
2305843009213690112
+) 96
-------------------------------------------------
2305843009213690112
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 101 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0101 0000 .0
.
2305843009213690112
+) 80
-------------------------------------------------
2305843009213690112
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 100 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0100 0000 .0
.
2305843009213690112
+) 64
-------------------------------------------------
2305843009213690112
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 11 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0011 0000 .0
.
2305843009213690112
+) 48
-------------------------------------------------
2305843009213690112
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 10 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0010 0000 .0
.
2305843009213690112
+) 32
-------------------------------------------------
2305843009213690112
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0001 0000 .0
.
2305843009213690112
+) 16
-------------------------------------------------
2305843009213690112
====================================================================================
......仮数部 LSB 0、小数点以下なし...(+n) + (+x)...............
...............................................
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1 0000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 1111 0000 0000 .0
.
2305843009213693440
+) 256
-------------------------------------------------
2305843009213693696
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1111 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 1110 1111 0000 .0
.
2305843009213693440
+) 240
-------------------------------------------------
2305843009213693696
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1110 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 1110 1110 0000 .0
.
2305843009213693440
+) 224
-------------------------------------------------
2305843009213693696
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1101 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 1110 1101 0000 .0
.
2305843009213693440
+) 208
-------------------------------------------------
2305843009213693696
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1100 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 1110 1100 0000 .0
.
2305843009213693440
+) 192
-------------------------------------------------
2305843009213693696
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1011 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 1110 1011 0000 .0
.
2305843009213693440
+) 176
-------------------------------------------------
2305843009213693696
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1010 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 1110 1010 0000 .0
.
2305843009213693440
+) 160
-------------------------------------------------
2305843009213693696
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1001 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 1110 1001 0000 .0
.
2305843009213693440
+) 144
-------------------------------------------------
2305843009213693696
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 1110 1000 0000 .0
.
2305843009213693440
+) 128
-------------------------------------------------
2305843009213693440
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 111 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 1110 0111 0000 .0
.
2305843009213693440
+) 112
-------------------------------------------------
2305843009213693440
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 110 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 1110 0110 0000 .0
.
2305843009213693440
+) 96
-------------------------------------------------
2305843009213693440
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 101 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 1110 0101 0000 .0
.
2305843009213693440
+) 80
-------------------------------------------------
2305843009213693440
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 100 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 1110 0100 0000 .0
.
2305843009213693440
+) 64
-------------------------------------------------
2305843009213693440
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 11 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 1110 0011 0000 .0
.
2305843009213693440
+) 48
-------------------------------------------------
2305843009213693440
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 10 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 1110 0010 0000 .0
.
2305843009213693440
+) 32
-------------------------------------------------
2305843009213693440
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 1110 0001 0000 .0
.
2305843009213693440
+) 16
-------------------------------------------------
2305843009213693440
====================================================================================
......仮数部 LSB 0、小数点以下なし...(-n) + (+x)...............
...............................................
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1 0000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 0000 0000 0000 .0
.
-2305843009213690112
+) 256
-------------------------------------------------
-2305843009213689856
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1111 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 0000 0001 0000 .0
.
-2305843009213690112
+) 240
-------------------------------------------------
-2305843009213689856
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1110 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 0000 0010 0000 .0
.
-2305843009213690112
+) 224
-------------------------------------------------
-2305843009213689856
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1101 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 0000 0011 0000 .0
.
-2305843009213690112
+) 208
-------------------------------------------------
-2305843009213689856
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1100 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 0000 0100 0000 .0
.
-2305843009213690112
+) 192
-------------------------------------------------
-2305843009213689856
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1011 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 0000 0101 0000 .0
.
-2305843009213690112
+) 176
-------------------------------------------------
-2305843009213689856
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1010 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 0000 0110 0000 .0
.
-2305843009213690112
+) 160
-------------------------------------------------
-2305843009213689856
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1001 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 0000 0111 0000 .0
.
-2305843009213690112
+) 144
-------------------------------------------------
-2305843009213689856
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 0000 1000 0000 .0
.
-2305843009213690112
+) 128
-------------------------------------------------
-2305843009213689856
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 111 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 0000 1001 0000 .0
.
-2305843009213690112
+) 112
-------------------------------------------------
-2305843009213690112
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 110 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 0000 1010 0000 .0
.
-2305843009213690112
+) 96
-------------------------------------------------
-2305843009213690112
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 101 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 0000 1011 0000 .0
.
-2305843009213690112
+) 80
-------------------------------------------------
-2305843009213690112
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 100 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 0000 1100 0000 .0
.
-2305843009213690112
+) 64
-------------------------------------------------
-2305843009213690112
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 11 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 0000 1101 0000 .0
.
-2305843009213690112
+) 48
-------------------------------------------------
-2305843009213690112
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 10 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 0000 1110 0000 .0
.
-2305843009213690112
+) 32
-------------------------------------------------
-2305843009213690112
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 0000 1111 0000 .0
.
-2305843009213690112
+) 16
-------------------------------------------------
-2305843009213690112
====================================================================================
......仮数部 LSB 1、小数点以下なし...(-n) + (+x)...............
...............................................
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1 0000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1101 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 1101 0000 0000 .0
.
-2305843009213693440
+) 256
-------------------------------------------------
-2305843009213693184
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1111 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1101 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 1101 0001 0000 .0
.
-2305843009213693440
+) 240
-------------------------------------------------
-2305843009213693184
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1110 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1101 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 1101 0010 0000 .0
.
-2305843009213693440
+) 224
-------------------------------------------------
-2305843009213693184
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1101 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1101 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 1101 0011 0000 .0
.
-2305843009213693440
+) 208
-------------------------------------------------
-2305843009213693184
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1100 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1101 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 1101 0100 0000 .0
.
-2305843009213693440
+) 192
-------------------------------------------------
-2305843009213693184
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1011 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1101 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 1101 0101 0000 .0
.
-2305843009213693440
+) 176
-------------------------------------------------
-2305843009213693184
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1010 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1101 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 1101 0110 0000 .0
.
-2305843009213693440
+) 160
-------------------------------------------------
-2305843009213693184
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1001 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1101 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 1101 0111 0000 .0
.
-2305843009213693440
+) 144
-------------------------------------------------
-2305843009213693184
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 1101 1000 0000 .0
.
-2305843009213693440
+) 128
-------------------------------------------------
-2305843009213693440
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 111 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 1101 1001 0000 .0
.
-2305843009213693440
+) 112
-------------------------------------------------
-2305843009213693440
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 110 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 1101 1010 0000 .0
.
-2305843009213693440
+) 96
-------------------------------------------------
-2305843009213693440
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 101 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 1101 1011 0000 .0
.
-2305843009213693440
+) 80
-------------------------------------------------
-2305843009213693440
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 100 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 1101 1100 0000 .0
.
-2305843009213693440
+) 64
-------------------------------------------------
-2305843009213693440
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 11 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 1101 1101 0000 .0
.
-2305843009213693440
+) 48
-------------------------------------------------
-2305843009213693440
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 10 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 1101 1110 0000 .0
.
-2305843009213693440
+) 32
-------------------------------------------------
-2305843009213693440
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
+) 1 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 0000 0000 .0
Binary Result(Subtract significant digits) => 11 1111 1111 1101 1111 0000 .0
.
-2305843009213693440
+) 16
-------------------------------------------------
-2305843009213693440
====================================================================================
......仮数部 LSB 0、小数点以下...(+n) + (+x)...............
...............................................
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1000 0000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1111 1000 0000
.
0.99999999999999977795539507496869
+) 0.00000000000000011102230246251565
-------------------------------------------------
0.99999999999999988897769753748435
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0111 1000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1111 0111 1000
.
0.99999999999999977795539507496869
+) 0.00000000000000010408340855860843
-------------------------------------------------
0.99999999999999988897769753748435
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0111 0000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1111 0111 0000
.
0.99999999999999977795539507496869
+) 0.00000000000000009714451465470120
-------------------------------------------------
0.99999999999999988897769753748435
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0110 1000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1111 0110 1000
.
0.99999999999999977795539507496869
+) 0.00000000000000009020562075079397
-------------------------------------------------
0.99999999999999988897769753748435
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0110 0000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1111 0110 0000
.
0.99999999999999977795539507496869
+) 0.00000000000000008326672684688674
-------------------------------------------------
0.99999999999999988897769753748435
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0101 1000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1111 0101 1000
.
0.99999999999999977795539507496869
+) 0.00000000000000007632783294297951
-------------------------------------------------
0.99999999999999988897769753748435
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0101 0000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1111 0101 0000
.
0.99999999999999977795539507496869
+) 0.00000000000000006938893903907228
-------------------------------------------------
0.99999999999999988897769753748435
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100 1000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1111 0100 1000
.
0.99999999999999977795539507496869
+) 0.00000000000000006245004513516506
-------------------------------------------------
0.99999999999999988897769753748435
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100 0000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1111 0100 0000
.
0.99999999999999977795539507496869
+) 0.00000000000000005551115123125783
-------------------------------------------------
0.99999999999999977795539507496869
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0011 1000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1111 0011 1000
.
0.99999999999999977795539507496869
+) 0.00000000000000004857225732735060
-------------------------------------------------
0.99999999999999977795539507496869
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0011 0000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1111 0011 0000
.
0.99999999999999977795539507496869
+) 0.00000000000000004163336342344337
-------------------------------------------------
0.99999999999999977795539507496869
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010 1000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1111 0010 1000
.
0.99999999999999977795539507496869
+) 0.00000000000000003469446951953614
-------------------------------------------------
0.99999999999999977795539507496869
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010 0000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1111 0010 0000
.
0.99999999999999977795539507496869
+) 0.00000000000000002775557561562891
-------------------------------------------------
0.99999999999999977795539507496869
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 1000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1111 0001 1000
.
0.99999999999999977795539507496869
+) 0.00000000000000002081668171172169
-------------------------------------------------
0.99999999999999977795539507496869
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 0000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1111 0001 0000
.
0.99999999999999977795539507496869
+) 0.00000000000000001387778780781446
-------------------------------------------------
0.99999999999999977795539507496869
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1111 0000 1000
.
0.99999999999999977795539507496869
+) 0.00000000000000000693889390390723
-------------------------------------------------
0.99999999999999977795539507496869
====================================================================================
......仮数部 LSB 1、小数点以下...(+n) + (+x)...............
...............................................
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1000 0000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1001 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1001 0000 0000
.
0.99999999999999833466546306226519
+) 0.00000000000000011102230246251565
-------------------------------------------------
0.99999999999999844568776552478084
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0111 1000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1001 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1000 1111 1000
.
0.99999999999999833466546306226519
+) 0.00000000000000010408340855860843
-------------------------------------------------
0.99999999999999844568776552478084
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0111 0000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1001 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1000 1111 0000
.
0.99999999999999833466546306226519
+) 0.00000000000000009714451465470120
-------------------------------------------------
0.99999999999999844568776552478084
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0110 1000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1001 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1000 1110 1000
.
0.99999999999999833466546306226519
+) 0.00000000000000009020562075079397
-------------------------------------------------
0.99999999999999844568776552478084
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0110 0000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1001 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1000 1110 0000
.
0.99999999999999833466546306226519
+) 0.00000000000000008326672684688674
-------------------------------------------------
0.99999999999999844568776552478084
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0101 1000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1001 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1000 1101 1000
.
0.99999999999999833466546306226519
+) 0.00000000000000007632783294297951
-------------------------------------------------
0.99999999999999844568776552478084
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0101 0000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1001 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1000 1101 0000
.
0.99999999999999833466546306226519
+) 0.00000000000000006938893903907228
-------------------------------------------------
0.99999999999999844568776552478084
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100 1000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1001 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1000 1100 1000
.
0.99999999999999833466546306226519
+) 0.00000000000000006245004513516506
-------------------------------------------------
0.99999999999999844568776552478084
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100 0000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1001 0000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1000 1100 0000
.
0.99999999999999833466546306226519
+) 0.00000000000000005551115123125783
-------------------------------------------------
0.99999999999999844568776552478084
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0011 1000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1000 1011 1000
.
0.99999999999999833466546306226519
+) 0.00000000000000004857225732735060
-------------------------------------------------
0.99999999999999833466546306226519
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0011 0000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1000 1011 0000
.
0.99999999999999833466546306226519
+) 0.00000000000000004163336342344337
-------------------------------------------------
0.99999999999999833466546306226519
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010 1000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1000 1010 1000
.
0.99999999999999833466546306226519
+) 0.00000000000000003469446951953614
-------------------------------------------------
0.99999999999999833466546306226519
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010 0000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1000 1010 0000
.
0.99999999999999833466546306226519
+) 0.00000000000000002775557561562891
-------------------------------------------------
0.99999999999999833466546306226519
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 1000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1000 1001 1000
.
0.99999999999999833466546306226519
+) 0.00000000000000002081668171172169
-------------------------------------------------
0.99999999999999833466546306226519
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 0000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1000 1001 0000
.
0.99999999999999833466546306226519
+) 0.00000000000000001387778780781446
-------------------------------------------------
0.99999999999999833466546306226519
====================================================================================
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1000
------------------------------------------------------------------------LGRS-oooo
0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
Binary Result(Add significant digits) =>xxxxx 111 1111 1111 1000 1000 1000
.
0.99999999999999833466546306226519
+) 0.00000000000000000693889390390723
-------------------------------------------------
0.99999999999999833466546306226519
====================================================================================
......仮数部 LSB 1、小数点以下...(-n) + (+x)...............
...............................................
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1000 0000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 1000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1110 1000 0000
.
-0.99999999999999977795539507496869
+) 0.00000000000000011102230246251565
-------------------------------------------------
-0.99999999999999966693309261245304
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0111 1000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 1000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1110 1000 1000
.
-0.99999999999999977795539507496869
+) 0.00000000000000010408340855860843
-------------------------------------------------
-0.99999999999999966693309261245304
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0111 0000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 1000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1110 1001 0000
.
-0.99999999999999977795539507496869
+) 0.00000000000000009714451465470120
-------------------------------------------------
-0.99999999999999966693309261245304
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0110 1000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 1000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1110 1001 1000
.
-0.99999999999999977795539507496869
+) 0.00000000000000009020562075079397
-------------------------------------------------
-0.99999999999999966693309261245304
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0110 0000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 1000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1110 1010 0000
.
-0.99999999999999977795539507496869
+) 0.00000000000000008326672684688674
-------------------------------------------------
-0.99999999999999966693309261245304
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0101 1000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 1000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1110 1010 1000
.
-0.99999999999999977795539507496869
+) 0.00000000000000007632783294297951
-------------------------------------------------
-0.99999999999999966693309261245304
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0101 0000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 1000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1110 1011 0000
.
-0.99999999999999977795539507496869
+) 0.00000000000000006938893903907228
-------------------------------------------------
-0.99999999999999966693309261245304
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100 1000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 1000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1110 1011 1000
.
-0.99999999999999977795539507496869
+) 0.00000000000000006245004513516506
-------------------------------------------------
-0.99999999999999966693309261245304
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100 0000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1110 1100 0000
.
-0.99999999999999977795539507496869
+) 0.00000000000000005551115123125783
-------------------------------------------------
-0.99999999999999977795539507496869
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0011 1000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1110 1100 1000
.
-0.99999999999999977795539507496869
+) 0.00000000000000004857225732735060
-------------------------------------------------
-0.99999999999999977795539507496869
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0011 0000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1110 1101 0000
.
-0.99999999999999977795539507496869
+) 0.00000000000000004163336342344337
-------------------------------------------------
-0.99999999999999977795539507496869
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010 1000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1110 1101 1000
.
-0.99999999999999977795539507496869
+) 0.00000000000000003469446951953614
-------------------------------------------------
-0.99999999999999977795539507496869
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010 0000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1110 1110 0000
.
-0.99999999999999977795539507496869
+) 0.00000000000000002775557561562891
-------------------------------------------------
-0.99999999999999977795539507496869
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 1000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1110 1110 1000
.
-0.99999999999999977795539507496869
+) 0.00000000000000002081668171172169
-------------------------------------------------
-0.99999999999999977795539507496869
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 0000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1110 1111 0000
.
-0.99999999999999977795539507496869
+) 0.00000000000000001387778780781446
-------------------------------------------------
-0.99999999999999977795539507496869
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1110 1111 1000
.
-0.99999999999999977795539507496869
+) 0.00000000000000000693889390390723
-------------------------------------------------
-0.99999999999999977795539507496869
====================================================================================
......仮数部 LSB 0、小数点以下...(-n) + (+x)...............
...............................................
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1000 0000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1000 0000 0000
.
-0.99999999999999833466546306226519
+) 0.00000000000000011102230246251565
-------------------------------------------------
-0.99999999999999822364316059974954
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0111 1000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1000 0000 1000
.
-0.99999999999999833466546306226519
+) 0.00000000000000010408340855860843
-------------------------------------------------
-0.99999999999999822364316059974954
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0111 0000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1000 0001 0000
.
-0.99999999999999833466546306226519
+) 0.00000000000000009714451465470120
-------------------------------------------------
-0.99999999999999822364316059974954
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0110 1000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1000 0001 1000
.
-0.99999999999999833466546306226519
+) 0.00000000000000009020562075079397
-------------------------------------------------
-0.99999999999999822364316059974954
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0110 0000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1000 0010 0000
.
-0.99999999999999833466546306226519
+) 0.00000000000000008326672684688674
-------------------------------------------------
-0.99999999999999822364316059974954
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0101 1000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1000 0010 1000
.
-0.99999999999999833466546306226519
+) 0.00000000000000007632783294297951
-------------------------------------------------
-0.99999999999999822364316059974954
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0101 0000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1000 0011 0000
.
-0.99999999999999833466546306226519
+) 0.00000000000000006938893903907228
-------------------------------------------------
-0.99999999999999822364316059974954
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100 1000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1000 0011 1000
.
-0.99999999999999833466546306226519
+) 0.00000000000000006245004513516506
-------------------------------------------------
-0.99999999999999822364316059974954
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100 0000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1000 0100 0000
.
-0.99999999999999833466546306226519
+) 0.00000000000000005551115123125783
-------------------------------------------------
-0.99999999999999822364316059974954
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0011 1000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1000 0100 1000
.
-0.99999999999999833466546306226519
+) 0.00000000000000004857225732735060
-------------------------------------------------
-0.99999999999999833466546306226519
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0011 0000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1000 0101 0000
.
-0.99999999999999833466546306226519
+) 0.00000000000000004163336342344337
-------------------------------------------------
-0.99999999999999833466546306226519
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010 1000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1000 0101 1000
.
-0.99999999999999833466546306226519
+) 0.00000000000000003469446951953614
-------------------------------------------------
-0.99999999999999833466546306226519
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010 0000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1000 0110 0000
.
-0.99999999999999833466546306226519
+) 0.00000000000000002775557561562891
-------------------------------------------------
-0.99999999999999833466546306226519
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 1000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1000 0110 1000
.
-0.99999999999999833466546306226519
+) 0.00000000000000002081668171172169
-------------------------------------------------
-0.99999999999999833466546306226519
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 0000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1000 0111 0000
.
-0.99999999999999833466546306226519
+) 0.00000000000000001387778780781446
-------------------------------------------------
-0.99999999999999833466546306226519
====================================================================================
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
+) 0 .0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1000
------------------------------------------------------------------------LGRS-oooo
-0 .1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 1000 0000
Binary Result(Subtract significant digits) => 111 1111 1111 1000 0111 1000
.
-0.99999999999999833466546306226519
+) 0.00000000000000000693889390390723
-------------------------------------------------
-0.99999999999999833466546306226519
====================================================================================
###### マイナス無限大方向への丸め : プラス値 ########################################################
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1 0000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0010 0000 0000 .0
.
2305843009213690112
+) 256
-------------------------------------------------
2305843009213690368
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 1000 0000 .0
.
2305843009213690112
+) 128
-------------------------------------------------
2305843009213690112
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 100 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0100 0000 .0
.
2305843009213690112
+) 64
-------------------------------------------------
2305843009213690112
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 10 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0010 0000 .0
.
2305843009213690112
+) 32
-------------------------------------------------
2305843009213690112
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0001 0000 .0
.
2305843009213690112
+) 16
-------------------------------------------------
2305843009213690112
====================================================================================
###### マイナス無限大方向への丸め : マイナス値 ########################################################
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
-) 1 0000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0010 0000 0000 .0
.
-2305843009213690112
-) 256
-------------------------------------------------
-2305843009213690368
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
-) 1000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 1000 0000 .0
.
-2305843009213690112
-) 128
-------------------------------------------------
-2305843009213690368
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
-) 100 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0100 0000 .0
.
-2305843009213690112
-) 64
-------------------------------------------------
-2305843009213690368
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
-) 10 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0010 0000 .0
.
-2305843009213690112
-) 32
-------------------------------------------------
-2305843009213690368
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
-) 1 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0001 0000 .0
.
-2305843009213690112
-) 16
-------------------------------------------------
-2305843009213690368
====================================================================================
###### ゼロ方向への丸め : プラス値 ########################################################
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1 0000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0010 0000 0000 .0
.
2305843009213690112
+) 256
-------------------------------------------------
2305843009213690368
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 1000 0000 .0
.
2305843009213690112
+) 128
-------------------------------------------------
2305843009213690112
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 100 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0100 0000 .0
.
2305843009213690112
+) 64
-------------------------------------------------
2305843009213690112
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 10 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0010 0000 .0
.
2305843009213690112
+) 32
-------------------------------------------------
2305843009213690112
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0001 0000 .0
.
2305843009213690112
+) 16
-------------------------------------------------
2305843009213690112
====================================================================================
###### ゼロ方向への丸め : マイナス値 ########################################################
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
-) 1 0000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0010 0000 0000 .0
.
-2305843009213690112
-) 256
-------------------------------------------------
-2305843009213690368
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
-) 1000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 1000 0000 .0
.
-2305843009213690112
-) 128
-------------------------------------------------
-2305843009213690112
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
-) 100 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0100 0000 .0
.
-2305843009213690112
-) 64
-------------------------------------------------
-2305843009213690112
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
-) 10 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0010 0000 .0
.
-2305843009213690112
-) 32
-------------------------------------------------
-2305843009213690112
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
-) 1 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0001 0000 .0
.
-2305843009213690112
-) 16
-------------------------------------------------
-2305843009213690112
====================================================================================
###### プラス無限大方向への丸め : プラス値 ########################################################
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1 0000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0010 0000 0000 .0
.
2305843009213690112
+) 256
-------------------------------------------------
2305843009213690368
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 1000 0000 .0
.
2305843009213690112
+) 128
-------------------------------------------------
2305843009213690368
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 100 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0100 0000 .0
.
2305843009213690112
+) 64
-------------------------------------------------
2305843009213690368
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 10 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0010 0000 .0
.
2305843009213690112
+) 32
-------------------------------------------------
2305843009213690368
====================================================================================
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
+) 1 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0001 0000 .0
.
2305843009213690112
+) 16
-------------------------------------------------
2305843009213690368
====================================================================================
###### プラス無限大方向への丸め : マイナス値 ########################################################
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
-) 1 0000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0010 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0010 0000 0000 .0
.
-2305843009213690112
-) 256
-------------------------------------------------
-2305843009213690368
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
-) 1000 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 1000 0000 .0
.
-2305843009213690112
-) 128
-------------------------------------------------
-2305843009213690112
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
-) 100 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0100 0000 .0
.
-2305843009213690112
-) 64
-------------------------------------------------
-2305843009213690112
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
-) 10 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0010 0000 .0
.
-2305843009213690112
-) 32
-------------------------------------------------
-2305843009213690112
====================================================================================
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
-) 1 0000 .0
---------------------------------------------------------------------L GRSo-oooo---
-1 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 .0
Binary Result(Add significant digits) =>xxxxx 11 1111 1111 0001 0001 0000 .0
.
-2305843009213690112
-) 16
-------------------------------------------------
-2305843009213690112
====================================================================================
2024-03-11 「Raspberry-pi 5」
Raspberry pi 5を使ってみた。
4Bの頃から紙箱に裸で入っている。
基板サイズは今までと同じ。ビス穴も同じ。USB,LANコネクタ配置は2B,3Bと同じ。
通常の電源はTDKラムダ スイッチング電源 5V dc 6A以上のものを使っている。
USB TypeA オス・USB TypeC オス ケーブルを使うと、
usb_max_current_enable default 0 max-current 900
と認識される。
そこで、
電源5Vー+ーーーーーーUSB VBUS5V USB-C オス・USB-C オス ケーブルでRaspi5の電源へ。
| 10kΩ
+---/\/\/\--USB-C A5 (CC1)
| 10kΩ
+---/\/\/\--USB-C B5 (CC2)
電源GNDーーーーーーーーUSB-C GND
とすると、
usb_max_current_enable default 0 max-current 3000
と認識される。
/boot/firmware/config.txtに「usb_max_current_enable=1」を設定すると上記のメッセージは出なかった。
5Aにさせるには、rpi-eeprom-config -eで「PSU_MAX_CURRENT=5000」と設定した。
カメラ picamera V2を接続した。
==== BOARD ( Memory 8.0MB ) ===
Raspberry Pi 5 Model B Rev 1.0
======= OS ( 64 Bits ) ========
Debian GNU/Linux 12 (bookworm)
===============================
/boot/firmware/config.txt に "camera_auto_detect=1"が記述してあるのでカメラを接続して自動検出する。
$ libcamera-hello -t 0
でエラーがでた。
「ERROR V4L2 v4l2_videodevice.cpp:1906 /dev/video4[16:cap]:
Failed to start streaming: Broken pipe
ERROR: *** failed to start camera ***」
$ libcamera-hello --list-camera
Available cameras
-----------------
0 : imx219 [3280x2464 10-bit RGGB] (/base/axi/pcie@120000/rp1/i2c@88000/imx219@10)
Modes: 'SRGGB10_CSI2P' : 640x480 [206.65 fps - (1000, 752)/1280x960 crop]
1640x1232 [41.85 fps - (0, 0)/3280x2464 crop]
1920x1080 [47.57 fps - (680, 692)/1920x1080 crop]
3280x2464 [21.19 fps - (0, 0)/3280x2464 crop]
'SRGGB8' : 640x480 [206.65 fps - (1000, 752)/1280x960 crop]
1640x1232 [83.70 fps - (0, 0)/3280x2464 crop]
1920x1080 [47.57 fps - (680, 692)/1920x1080 crop]
3280x2464 [21.19 fps - (0, 0)/3280x2464 crop]
接続カメラのリストは表示される。
libcamera-* は、リネームされて rpicam-* となっている。
"Raspberry pi 5 v4l2 Broken pipe"で検索して、
検索結果:https://github.com/raspberrypi/libcamera/issues/104
libcamera-apps fail to run V2 camera on RPi5 #104
の中にあった以下のコマンドを実行。
$ sudo rpi-update d16727d
$ sudo reboot
するとエラーがでなくなり、カメラが動作するようになる。
参照:https://www.raspberrypi.com/documentation/computers/camera_software.html
Raspberry Pi Documentation
Camera software
2B,3BケースのUSB,LANコネクタ穴に収まる。電源USB-C,HMDI 2個のコネクタが刺さるように穴を広げて、
電源SWの頭が基板端より少し出ているのでそこに穴を開ければ収まる。CPU上の板状の部分も取るといいかも。
メモリ基板 「Geekworm X1000 Pcie M.2 Key-M NVMe SSD拡張ボード」と
メモリ 「Samsung SSD 256GB PM991 M.2 2242 42mm PCIe 3.0 x4 NVMe MZALQ256HAJD MZALQ2560 ソリッドス
テートドライブ」追加してみました。
2.4Ghz WIFIは、大きな解像度(1920x1080)のディスプレイを接続しても接続できる。
Raspi4Bは、接続できない、できにくいことが多かった。
処理速度は早い。
USBブートは設定を変えること。
raspi-config の Advanced Options の A4 Boot Order の B2 にする。
リブートしてもUSBブートはしない。
ACアダプタONでも自動USBブートしない。
POWER SWを押すとUSBブートする。(ちょっと面倒)
POWER SWを押すまではFANが回る。
FANは常に回るわけではない。
USBデバイスでブートする場合
●POWER SWの扱い
電源断状態から、ACアダプタで電源ONにして、ディスプレイに文字メッセージ表示のみになる。
このとき1回 短押しするとUSBブートを始め、OSが起動する。
デスクトップ表示中に短押しすると、シャットダウンポップアップメニューが出る。もう1回短押しするとシャットダウンし、ディスプレイ表示なしとなる。
このとき5V電源は、電流が流れておりCPUは動作している。
ディスプレイ表示なしのこのときPOWER SW短押しするとOS起動する。
デスクトップ表示中にPOWER SWを長押ししたままでシャットダウンしてディスプレイ表示なしになる。このとき5V電源は電流はほぼゼロとなっている。
ディスプレイ表示なし、5V電源は電流はほぼゼロのとき、 POWER SW短押しすると、ディスプレイに文字メッセージ表示されたら、もう1回短押しするとOS起動する。
SDカードよりブートする場合
●POWER SWの扱い
電源断状態から、ACアダプタで電源ONにして、ディスプレイに文字メッセージ表示し、自動でOSが起動する。
デスクトップ表示中に短押しすると、シャットダウンポップアップメニューが出る。もう1回短押しするとシャットダウンし、ディスプレイ表示なしとなる。
このとき5V電源は、電流が流れておりCPUは動作している。
ディスプレイ表示なしのこのときPOWER SW短押しするとOS起動する。
デスクトップ表示中にPOWER SWを長押ししたままでシャットダウンしてディスプレイ表示なしになる。このとき5V電源は電流はほぼゼロとなっている。
ディスプレイ表示なし、5V電源は電流はほぼゼロとき、 POWER SW短押しすると、ディスプレイに文字メッセージ表示されたら、自動でがOS起動する。
ドキュメントに書いてありました。
/boot/firmware/config.txt に usb_max_current_enable=1 を追加設定すれば自動起動すると。
POWER SWを押す回数が多そうなのでプッシュSWを追加した。
(昔のPCマザーボードについていたリセットSW)
短押し2回では電流が0.3Aほど流れている。ディスプレイは表示なし。
シリアルコンソールは動作しない。(電流が流れているので変な期待をしたのがバカだった)
その後短押し1回でOSが起動する。
電流が0.3Aほど流れているとき、
https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#POWER_OFF_ON_HALT
より、
デフォルトではPMIC出力ありになっている。
LEDは赤色。ここでPWER SWを長押しするとLEDは赤色から緑色になってまた赤色となる。
このとき5V電源は電流はほぼゼロ。
roi-eeprom-config -e で”POWER_OFF_ON_HALT=1”にするとshutdownで電流はセロになる。
長押ししたままでシャットダウンしてディスプレイ表示なしに、短押し1回でOSが起動する。
USB電源入れ直すと自動でUSBブートする。
デスクトップ表示中に短押しすると、シャットダウンポップアップメニューが出るのは、WaylandのときでX11でDesktop表示では
短押しでは。シャットダウンポップアップメニューが出ない。長押しのみ有効。
アナログTVコンポジット出力を試してみた。
RasPi5基板のコンポジット信号出力パターン穴に接続する。
/boot/firmware/config.txt に
#dtoverlay=vc4-kms-v3d
dtoverlay=vc4-kms-v3d-pi5,composite
と修正する。再起動でTVに表示される。
2024-02-25 「BITBANGソフトウェアI2C」
雑誌インターフェース2024・3月号のソフトウェアI2C(I2C bitbang)を見てちょっと面倒そうだなと思って真似てやってみた。
I2C接続はオープンドレインで、誰かがLOWにしたら全部LOW検出のしくみで混乱してしまった。
テスト用にAVR ATTiny85でI2Cスレーブデバイスを作成し、PICOでBME280と一緒にテストする。
参考:
NXP I2Cドキュメント UM1024.pdf (日本語、英語)
トランジスタ技術 2014・10月号 2線シリアル・インターフェースI2C詳解 (p152-176)
PICOオープンドレインテストの配線。
PICO
3.3V -----/\/10KΩ\/\---+---▶|(LED)---/\/1KΩ\/\---> GND
GP28 ------------------+
micropython のPICOオープンドレインテストプログラム
手で入力実行。
---
from machine import Pin
out = Pin(28)
out.init(Pin.OPEN_DRAIN)
out.value(0) # LED消灯
out.value(1) # LED薄く点灯
out.init(Pin.OUT)
out.value(0) # LED消灯
out.value(1) # LED点灯
==== BOARD ( Memory 8.0MB ) ===
Raspberry Pi 4 Model B Rev 1.5
======= OS ( 64 Bits ) ========
Debian GNU/Linux 12 (bookworm)
===============================
Raspberry pi書き込み用GPIO接続
ピン17,1:3.3V ーー> ATTINY85 pin8(VDD)
ピン19:MOSI(GPO10) ーー> ATTINY85 pin5(MOSI)
ピン21:MISO(GPIO9) ーー> ATTINY85 pin6(MISO)
ピン23:CLK(GPIO11) ーー> ATTINY85 pin7(CLK)
ATTINY85 pin8(VDD) --[10 kΩ]-- ATTINY85 pin1(RESET) pull up
ピン37:GPIO26 ーー> ATTINY85 pin1(RESET)
ピン6,39:GND ーー> ATTINY85 pin4(GND)
ヒューズビットが外付けXtal,セラミック発振子の場合はつけること。
インストール
sudo apt-get install gcc-avr avr-libc binutils-avr avrdude
sudo nano /etc/avrdude.conf
----修正 コメントを取る-----
programmer
id = "linuxgpio";
desc = "Use the Linux sysfs interface to bitbang GPIO line>
type = "linuxgpio";
prog_modes = PM_ISP;
reset = 26;
sck = 11;
sdo = 10;
sdi = 9;
;
https://yetanotherhackersblog.wordpress.com/2011/04/12/interfacing-the-beagleboard-with-an-attiny85-microcontroller-over-i2c/
Yet Another Hacker's Blog - Interfacing the BeagleBoard with an ATtiny85 Microcontroller over I2C
” You can download the code from here (its an AVR Studio project for AVR GCC).”
の「here」をクリック。
にあったリンクのソース ↓
https://storage.googleapis.com/google-code-archive-source/v2/code.google.com/usi-i2c-slave/source-archive.zip
をもらってきて、修正。
-----i2ctest.c -------
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay_basic.h>
#include "usiTwiSlave.h"
#include <avr/cpufunc.h>
#define I2C_SLAVE_ADDR 0x26
#define PIEZO PB1
#define GPIO_PIN PB3
// Somewhere to store the values the master writes to i2c register.
static volatile uint8_t pinb = 0;
static volatile uint8_t adc_data = 0;
void adcInit() {
// Enable ADC2/PB4 as ADC input
ADMUX |= 1 << MUX1;
// Set the ADC clock precaler to 16 (ie 500KHz if the main clock is 8MHz).
ADCSRA |= 1 << ADPS2;
// Left align the output (this lets us just use the 8 bits in the ADCH output register (we
// can ignore the extra 2 bits in the ADCL register).
ADMUX |= 1 << ADLAR;
// Enable ADC.
ADCSRA |= 1 << ADEN;
}
uint8_t adcRead() {
// Start a conversion
ADCSRA |= 1 << ADSC;
// Wait for it to finish
while (ADCSRA & (1 << ADSC));
// Get the result.
return ADCH;
}
void on_buzz()
{
TCCR0A &= 0xCF; // Stop OC0B
TCCR0A |= 0x10; // out OC0B
}
void off_buzz()
{
TCCR0A &= 0xCF; // Stop OC0B
PORTB &= ~(1 << PIEZO);
}
// A callback triggered when the i2c master attempts to read from a register.
uint8_t i2cReadFromRegister(uint8_t reg)
{
uint8_t r;
switch (reg)
{
case 0: // read PB3
if ( DDRB & (1 << PB3) ) {
DDRB &= ~(1 << PB3);
r = PINB;
}
if ( PINB & (1<<PB3)) {
r = 1;
} else {
r = 0;
}
return r;
case 1: // read ADC
return adc_data;
default:
return 0xAA;
}
}
// A callback triggered when the i2c master attempts to write to a register.
void i2cWriteToRegister(uint8_t reg, uint8_t value)
{
switch (reg)
{
case 0: // write PB3
DDRB |= (1 << PB3);
if ( value & 1 )
PORTB |= 1 << PB3;
else
PORTB &= ~(1 << PB3);
break;
case 1: // write ON/OFF buzzer
if( value & 1 )
on_buzz();
else
off_buzz();
break;
}
}
ISR(TIM1_OVF_vect)
{
adc_data = adcRead();
}
void init_int(void)
{
// Timer0
TCCR0A = 0x00;
TCCR0B = 0x00;
TCCR0A = 0x02; // OC0B out / CTC
TCCR0B = 0x03; // 2 Mhz / (64 [TCCR0B.CS0] * 2 * (n[OCR0A] - 1) ) = f(Hz)
OCR0A = 38; // 400Hz
// Timer1
TCCR1 = 0xcc; // CK / 2048 -- OCR1C on zero cntr
OCR1C = 100; // 2Mhz / 2048 / 100 = 100ms
TIMSK |= 0x04;
}
int main()
{
CLKPR = 0x80;
CLKPR = 0x02; // 8Mhz/4 =2000000hz
// Set the LED pin as output.
DDRB |= (1 << PIEZO);
PORTB = (1 << PIEZO) ^ 0x3F; // in pull up
init_int();
adcInit();
usiTwiSlaveInit(I2C_SLAVE_ADDR, i2cReadFromRegister, i2cWriteToRegister);
sei();
while (1)
{
_NOP();
}
}
----
コンパイル
avr-gcc i2ctest.c usiTwiSlave.c -o i2cdev -Wall -Os -std=gnu99 -mmcu=attiny85 -I.
avr-objcopy -O ihex 12cdev i2cdev.hex
プログラム書き込み
sudo avrdude -p t85 -P linuxgpio -c linuxgpio -v -U flash:w:i2cdev.hex
ヒューズビット書き込み
sudo avrdude -p t85 -c linuxgpio -P linuxgpio -v -U lfuse:w:0x72:m -U hfuse:w:0xDF:m -U efuse:w:0xFF:m
ATTiny85を試す。
i2cdetect -y 1
0x26 があること
・・・I2Cスレーブ機能
書き込みは、2バイト。
1バイト目 2バイト目
0 0x01 (PB3 Hi - LED点灯) or 0x00 (PB3 Low - LED消灯)
1 0x01 (PB1 - ピエゾ鳴く) or 0x00 (PB1 - ピエゾ消音)
読み込みは、1バイト機能指定、1バイト読み込み。
1バイト目 読み込み値
0 PB3 の値 Hi - 1 or Low - 0
1 PB4 ADC値 0 ~ 255
・・・
Raspberry PICOには、BME280と作成したATTiny85とLED、抵抗、ピエゾ、SW、ボリューム抵抗を配線する。
PICO配線
micropython のI2Cテストプログラム
---test.py---
from machine import Pin, I2C
from time import sleep
i2c = I2C(0, sda = Pin(0), scl = Pin(1), freq = 40000)
adr = i2c.scan()
adr_lst = list(hex(a) for a in adr)
print("Addr:", adr_lst)
i2c.writeto(0x26,b'\x01\x01')
sleep(0.5)
i2c.writeto(0x26,b'\x01\x00')
---
ブザーが鳴る。
micropython BitbangソフトI2C のテストプログラム。
--i2c-bme280-attiny85.py---
from machine import Pin
def SDA_BIT():
return sda.value()
def I2C_INIT2():
sda.init(Pin.OUT, Pin.OPEN_DRAIN)
scl.init(Pin.OUT, Pin.OPEN_DRAIN)
sda.value(1)
scl.value(1)
def SDA_HIGH2():
sda.value(1)
def SDA_LOW2():
sda.value(0)
def SCL_HIGH2():
scl.value(1)
def SCL_LOW2():
scl.value(0)
# ========================
def start_condition():
SCL_HIGH2()
SDA_LOW2()
def stop_condition():
SDA_LOW2()
SCL_HIGH2()
SDA_HIGH2()
def send_byte( byte ):
for i in range(8):
SCL_LOW2()
if byte & (0x80>>i):
SDA_HIGH2()
else:
SDA_LOW2()
SCL_HIGH2()
# getting ACK/NACK
SCL_LOW2()
SDA_HIGH2()
SCL_HIGH2()
nack = SDA_BIT()
SCL_LOW2()
return nack
def recv_byte(nack):
b = 0
SDA_HIGH2()
for i in range(8):
b <<= 1
SCL_LOW2()
SCL_HIGH2()
b |= SDA_BIT()
SCL_LOW2()
if nack:
SDA_HIGH2() # Last byte NACK
else:
SDA_LOW2()
SCL_HIGH2()
SCL_LOW2()
return b
def p_out(adr, reg, data):
start_condition()
if send_byte( adr<<1|0 ): # Write
stop_condition()
print("Error OUTPUT:%02X / REG:%02X" % (adr, reg))
return
send_byte( reg )
send_byte( data )
stop_condition()
def p_in(adr,reg):
start_condition()
if send_byte( adr<<1|0 ): # Write
stop_condition()
print("Error INPUT:%02X / REG:%02X" % (adr, reg))
return
send_byte( reg )
start_condition()
send_byte( adr<<1|1 ) # Read
data = recv_byte(True) # 1byte NACK
stop_condition()
print("REG(%02X):%02X %d" % (reg,data,data))
import time
sda = Pin(0)
scl = Pin(1)
I2C_INIT2()
print("*** DUMP REGISTER ***")
print("BME280 ID : 0x60")
p_in(0x76, 0xD0)
print("BME280 制御")
print("BME280 Reg F2 : 0x01")
p_out(0x76, 0xF2,0x01)
print("BME280 Reg F4 : 0x27")
p_out(0x76, 0xF4,0x27)
print("BME280 Reg F5 : 0xA0")
p_out(0x76, 0xF5,0xA0)
p_in(0x76, 0xF2)
p_in(0x76, 0xF4)
p_in(0x76, 0xF5)
print("--ATTiny85 I2C--")
print("--OUT-- led ON, BUZZ on")
p_out(0x26, 0, 1) # led on
p_out(0x26, 1, 1) # buzz on
time.sleep(0.5)
print("--OUT-- led OFF, BUZZ off")
p_out(0x26, 0, 0) # led off
p_out(0x26, 1, 0) # buzz off
print("--IN--")
p_in(0x26, 0) # PB3 in
p_in(0x26, 1) # ADC in
time.sleep(0.5)
print("--OUT-- led ON, BUZZ on")
p_out(0x26, 0, 1) # led on
p_out(0x26, 1, 1) # buzz on
time.sleep(0.5)
print("--OUT-- led OFF, BUZZ off")
p_out(0x26, 0, 0) # led off
p_out(0x26, 1, 0) # buzz off
----
結果
...
MPY: soft reboot
*** DUMP REGISTER ***
BME280 ID : 0x60
REG(D0):60 96
BME280 制御
BME280 Reg F2 : 0x01
BME280 Reg F4 : 0x27
BME280 Reg F5 : 0xA0
REG(F2):01 1
REG(F4):27 39
REG(F5):A0 160
--ATTiny85 I2C--
--OUT-- led ON, BUZZ on
--OUT-- led OFF, BUZZ off
--IN--
REG(00):00 0 <<==SW ONで1、OFFで0
REG(01):B5 181 <<==ボリューム位置で変わる 0〜255
--OUT-- led ON, BUZZ on
--OUT-- led OFF, BUZZ off
...
2024-01-17 「seed studio XIAO ESP32S3 Micropythonインストール」
seed studio XIAO ESP32S3 にMicropythonをインストールしてみた。
2023-12-05 arm64 bookworm DeskTop Full イメージを使う。
==== BOARD ( Memory 8.0MB ) ===
Raspberry Pi 4 Model B Rev 1.5
======= OS ( 64 Bits ) ========
Debian GNU/Linux 12 (bookworm)
===============================
ESP32-S3 micropythonダウンロード。
https://micropython.org/download/ESP32_GENERIC_S3/
https://micropython.org/resources/firmware/ESP32_GENERIC_S3-SPIRAM_OCT-20240105-v1.22.1.bin
apt install でESPTOOLがインストールできないので、
https://github.com/espressif/esptool/releases
より、 esptool-v4.7.0-arm64.zip ダウンロード。
解凍。
$ cd esptool-arm64
$ chmod +x esptool
$ ./esptool --help
ヘルプが表示されること。
USBケーブル差し込む。
boot SWを押しながら、reset swをプッシュ、boot swをはなす。
(SWが小さい、扱いが雑だったのでBeset SWの上の盛り上がった接触接点が剥がれた)
$ ./esptool --port /dev/ttyACM0 chip_id
====
esptool.py v4.7.0
Serial port /dev/ttyACM0
Connecting...
Detecting chip type... ESP32-S3
Chip is ESP32-S3 (QFN56) (revision v0.2)
Features: WiFi, BLE, Embedded PSRAM 8MB (AP_3v3)
Crystal is 40MHz
MAC: dc:da:0c:57:ab:c0
Uploading stub...
Running stub...
Stub running...
Warning: ESP32-S3 has no Chip ID. Reading MAC instead.
MAC: dc:da:0c:57:ab:c0
Hard resetting via RTS pin...
===
$ ./esptool --chip esp32s3 --port /dev/ttyACM0 erase_flash
esptool.py v4.7.0
Serial port /dev/ttyACM0
Connecting...
Chip is ESP32-S3 (QFN56) (revision v0.2)
Features: WiFi, BLE, Embedded PSRAM 8MB (AP_3v3)
Crystal is 40MHz
MAC: dc:da:0c:57:ab:c0
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 2.7s
Hard resetting via RTS pin...
===
$ ./esptool --chip esp32s3 --port /dev/ttyACM0 write_flash -z 0 ESP32_GENERIC_S3-SPIRAM_OCT-20240105-v1.22.1.bin
===
esptool.py v4.7.0
Serial port /dev/ttyACM0
Connecting...
Chip is ESP32-S3 (QFN56) (revision v0.2)
Features: WiFi, BLE, Embedded PSRAM 8MB (AP_3v3)
Crystal is 40MHz
MAC: dc:da:0c:57:ab:c0
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Flash will be erased from 0x00000000 to 0x0018efff...
Compressed 1631504 bytes to 1068949...
Wrote 1631504 bytes (1068949 compressed) at 0x00000000 in 10.0 seconds (effective 1298.8 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
===
$ minicom -b 115200 -D /dev/ttyACM0
===
>>> help('modules')
__main__ bluetooth heapq select
_asyncio btree inisetup socket
_boot builtins io ssl
_espnow cmath json struct
_onewire collections machine sys
_thread cryptolib math time
_webrepl deflate micropython uasyncio
aioespnow dht mip/__init__ uctypes
apa106 ds18x20 neopixel umqtt/robust
array errno network umqtt/simple
asyncio/__init__ esp ntptime upysh
asyncio/core esp32 onewire urequests
asyncio/event espnow os webrepl
asyncio/funcs flashbdev platform webrepl_setup
asyncio/lock framebuf random websocket
asyncio/stream gc re
binascii hashlib requests/__init__
Plus any modules on the filesystem
>>>
=====
または、Thonnyシェルで。
配線: XIAO ESP32S3
+-----/\/1kΩ/\----|◁---ESP32 GPIO 6
| LED
▽
+--/\/10kΩ/\------------ESP32 3V3
|
+-----------------------ESP32 GPIO 7
|
○ |
|= SW
○ |
|
▽
Rasberry pi ==== USBケーブル ==== ESP32
Thonnyで実行
--- sw-led.py ----
from machine import Pin
import time
user_led = Pin(21, Pin.OUT)
user_led.value(0)
led = Pin(6, Pin.OUT)
led.value(0)
sw = Pin(7, Pin.IN)
while True:
user_led.value(user_led.value() ^ 1)
if sw.value():
led.value(0)
else:
led.value(1)
time.sleep(0.5)
-----
実行
ユーザLEDが点滅、SW ONでLEDが点灯。
2023-12-20 「PICO-W ble キーボード」
参考:
https://forums.raspberrypi.com/viewtopic.php?t=347395
Running the BT demo programs - encouraged!
https://github.com/bluekitchen/btstack
Welcome to BTstack
https://forums.raspberrypi.com/viewtopic.php?t=356457
Trying to turn Pico W into a Bluetooth keyboard
https://technotes.kynetics.com/2018/BLE_Pairing_and_bonding/
BLE Pairing and Bonding
https://bluekitchen-gmbh.com/btstack/
BTstack Manual master-486107eca
https://bluekitchen-gmbh.com/btstack/#examples/examples/
LE Peripheral - Test Pairing Methods
Main Application Setup
(LE Secure Connections, Just Works)
Raspberry PICO-W でBluetoothキーボードを作ってみました。
NRF51822 Blutooth基板 BBC Micro:bit、BBC Micro:bit V2はnRF52833 と同じように接続するものです。
PICO-Wのサンプルは、ペアリング条件により接続できないスマホがあるが,ペアリング条件を変えると接続するようになる。
ペアリング条件はレガシーなので注意する必要があります。
キーボードマトリックス入力は、Microchip MCP23S17 2個でSPI経由で入力。
ble-keyboard
├── CMakeLists.txt
├── build
├── hog_keyboard_demo.c
├── hog_keyboard_demo.gatt
├── keyboard.c
└── keyboard.h
CMakefiles.txt
...
set(PROJECT hog_keyboard_demo)
set(PICO_BOARD pico_w)
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
cmake_minimum_required(VERSION 3.12)
include(${PICO_SDK_PATH}/external/pico_sdk_import.cmake)
project(${PROJECT} C CXX ASM)
pico_sdk_init()
add_executable(${PROJECT}
hog_keyboard_demo.c
keyboard.c
)
target_link_libraries(${PROJECT}
pico_stdlib
pico_btstack_ble
pico_btstack_classic #not needed for BLE only demos
pico_btstack_cyw43
pico_cyw43_arch_none
hardware_spi
)
pico_enable_stdio_usb(${PROJECT} 1)
pico_enable_stdio_uart(${PROJECT} 0)
target_include_directories(${PROJECT} PRIVATE
${CMAKE_CURRENT_LIST_DIR}
${PICO_SDK_PATH}/../pico-examples/pico_w/bt/config
)
pico_btstack_make_gatt_header(${PROJECT} PRIVATE "${CMAKE_CURRENT_LIST_DIR}/hog_keyboard_demo.gatt")
pico_add_extra_outputs(${PROJECT})
....
hog_keyboard_demo.gatt examples ソースディレクトリよりコピー
static uint8_t protocol_mode = 1; // mode = 0 にするとキー入力しない。
(1)sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_ONLY);
sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION | SM_AUTHREQ_BONDING);
Windows11は入力できるが、Androidスマホはペアリングできない。
(2)// ======= LE Secure Connections, Just Works =============
sm_set_io_capabilities(IO_CAPABILITY_NO_INPUT_NO_OUTPUT);
sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION| SM_AUTHREQ_BONDING);
Windows11, Android, Raspberry pi ペアリング、キー入力できる。
回路
ソースプログラム
[ble-keyboard.tgz] 7.4Kb
2023-11-18 「NFS ポート番号固定設定」
参考1:https://ny55.blogspot.com/2016/12/how-to-configure-static-ports-for-nfs.html
How To Configure Static Ports for NFS on Linux
・・・・・・
NFS サーバが使用するポートは,111, 2049のUDP,TCPはきまっているが他は不定なのでDockerコンテナでは
NFSサーバが作りにくいので固定する。RPCクォータは使用しない。
==== BOARD ( Memory 4.0MB ) ===
Raspberry Pi 4 Model B Rev 1.2
======= OS ( 64 Bits ) ========
Debian GNU/Linux 12 (bookworm)
===============================
$ uname -a
Linux 49e189bedc2c 6.1.0-rpi4-rpi-v8 #1 SMP PREEMPT Debian 1:6.1.54-1+rpt2 (2023-10-05) aarch64 GNU/Linux
★インストール
$ ssudo apt install -y nfs-kernel-server
$ sudo nano /etc/exports
---
/export 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash,all_squash)
--- 追加
$ sudo nano /etc/nfs.conf
---
[lockd]
port=32767
udp-port=32767
;;
[mountd]
port=32766
# debug="all|auth|call|general|parse"
manage-gids=y
;;
[statd]
port=32765
outgoing-port=32764
;;
---修正
$ sudo systemctl stop nfs-kernel-server
$ sudo systemctl restart portmap
$ sudo systemctl start nfs-kernel-server
$ sudo mount -t nfs 192.168.1.xxx:/export /home/dkr
■■■■■■■■■
Dockerコンテナ
(1)Dockerfile
....
FROM arm64v8/debian
MAINTAINER “K.Shimoura"
ENV container docker
ENV DEBIAN_FRONTEND noninteractive
# SIGNAL=37
STOPSIGNAL SIGRTMIN+3
# root パスワード設定
RUN printf "rootdocker\nrootdocker\n"| passwd > /dev/null 2>&1
RUN apt update
# ロケール設定
RUN apt install -y locales locales-all
ENV LC_ALL ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP.UTF-8
ENV TZ Asia/Tokyo
RUN echo 'export LC_ALL="ja_JP.UTF-8"' >> /etc/profile
RUN echo 'export LANG="ja_JP.UTF-8"' >> /etc/profile
RUN echo 'export LANGUAGE="ja_JP:jp"' >> /etc/profile
RUN echo 'export TZ="Asia/Tokyo"' >> /etc/profile
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# install rc.local
COPY rc.local /etc/rc.local
RUN chmod +x /etc/rc.local
RUN echo "/etc/rc.local" >> /usr/bin/entry.sh
# NFS
RUN apt install -y init
RUN apt install -y nano
RUN apt install -y nfs-kernel-server
RUN sed -i -e "/^\[statd\]/a port=32765\\noutgoing-port=32764\\n" /etc/nfs.conf
RUN sed -i -e "/^\[mountd\]/a port=32766\\n" /etc/nfs.conf
RUN sed -i -e "/^\[lockd\]/a port=32767\\nudp-port=32767\\n" /etc/nfs.conf
RUN echo "/export 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash,all_squash)" >> /etc/exports
RUN apt install -y procps
CMD ["/usr/sbin/init"]
....
(2)コンテナ作成
$ docker build -t arm64/nfs .
(3)コンテナ実行
$ docker run --privileged -ti --rm -v /home/pi/DOCKER:/export -p 111:111 -p 111:111/udp -p 2049:2049 -p 2049:2049/udp -p 32764-32767:32764-32767 -p 32764-32767:32764-32767/udp --name nfs arm64/nfs
ディレクトリの"/home/pi/DOCKER"はext4形式のこと。ext4形式以外だとNFSがエクスポートしない。
(4)NFSマウント 他のPCで
$ sudo mount -t nfs 192.168.1.xxx:/export /home/dkr
2025-03-10 「Raspbery pi PICO-W micorpythonをソースから作る」
Raspberry pi PICO WのMicropythonをソースから作ってみた。
参照:
https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html#pico-1-family
Pico 1 family
Documentation
Raspberry Pi Pico W
Software Development
-- Raspberry Pi Pico C/C++ SDK, Raspberry Pi Pico Python SDK
-- For instructions on how to use the debugger, see Getting Started with Pico-series Microcontrollers.
getting-started-with-pico.pdf (15 October 2024)
"Appendix C: Manual toolchain setup"
Use the CLI to Blink an LED in C
connecting-to-the-internet-with-pico-w.pdf (25 November 2024)
"Appendix A: Building MicroPython from source"
raspberry-pi-pico-c-sdk.pdf (20 February 2025)
環境は
==== BOARD ( Memory 4.0MB ) ===
Raspberry Pi 5 Model B Rev 1.0
======= OS ( 64 Bits ) ========
Debian GNU/Linux 12 (bookworm)
===============================
手順は
$ mkdir ~/pico
$ cd ~/pico
$ wget https://raw.githubusercontent.com/raspberrypi/pico-setup/master/pico_setup.sh
$ chmod +x pico_setup.sh
$ ./pico_setup.sh
$ sudo reboot
例題コンパイル
$ cd ~/pico/pico/pico-examples/build_pico
$ export PICO_SDK_PATH=../../pico-sdk
$ cmake -DPICO_BOARD=pico_w -DWIFI_SSID="Your Network" -DWIFI_PASSWORD="Your Password" ..
$ make
MICROPYTHONコンパイル
micropythonソースは、
pico
└── pico
├── micropython
├── micropython-lib
├── openocd
├── pico-examples
├── pico-extras
├── pico-playground
├── pico-sdk
├── picoprobe
└── picotool
になるように、git cloneする。
firmware.uf2をPICOに書き込む。
$ cd ~/pico/pico
$ git clone https://github.com/micropython/micropython.git --branch master
$ git clone https://github.com/micropython/micropython-lib.git --branch master
$ cd micropython
$ make -C ports/rp2 BOARD=RPI_PICO_W submodules
$ make -C mpy-cross
$ cd ports/rp2
$ make BOARD=RPI_PICO_W
$ ls build-RPI_PICO_W
...
CMakeCache.txt firmware.dis frozen_mpy pins_RPI_PICO_W.c
CMakeFiles firmware.elf generated pioasm
Makefile firmware.elf.map genhdr pioasm-install
_deps firmware.hex pico-sdk submodules
cmake_install.cmake firmware.uf2 pico_flash_region.ld
...
$ picotool info -a build-RPI_PICO_W/firmware.uf2
...
File build-RPI_PICO_W/firmware.uf2 family ID 'rp2040':
Program Information
name: MicroPython
version: v1.25.0-preview.365.g3823aeb0f
features: thread support
USB REPL
frozen modules: aioble/security, aioble/l2cap, aioble/client,
aioble/central, aioble/server, aioble/peripheral,
aioble/device, aioble/core, aioble, urequests,
webrepl_setup, webrepl, ssl, ntptime, mip, requests,
neopixel, dht, ds18x20, onewire, uasyncio, asyncio/stream,
asyncio/lock, asyncio/funcs, asyncio/event, asyncio/core,
asyncio, rp2, _boot, _boot_fat
binary start: 0x10000000
binary end: 0x100d5278
embedded drive: 0x1012c000-0x10200000 (848K): MicroPython
Fixed Pin Information
none
Build Information
sdk version: 2.1.1
pico_board: pico_w
boot2_name: boot2_w25q080
build date: Mar 9 2025
build attributes: MinSizeRel
Metadata Blocks
none
..
--------
上記の手順で、
debugprobe.uf2
firmware.uf2
adc_console.uf2
adc_dma_capture.uf2
hello_adc.uf2
joystick_display.uf2
microphone_adc.uf2
onboard_temperature.uf2
read_vsys.uf2
blink_any.uf2
hello_anything.uf2
blink.uf2
blink_simple.uf2
clocks_detached_clk_peri.uf2
hello_48MHz.uf2
hello_gpout.uf2
hello_resus.uf2
build_variant1.uf2
build_variant2.uf2
hello_divider.uf2
dma_channel_irq.uf2
dma_control_blocks.uf2
hello_dma.uf2
sniff_crc.uf2
flash_cache_perfctr.uf2
flash_nuke.uf2
flash_program.uf2
flash_ssi_dma.uf2
flash_xip_stream.uf2
dht.uf2
hello_7segment.uf2
hello_gpio_irq.uf2
hello_serial.uf2
hello_usb.uf2
bmp280_i2c.uf2
i2c_bus_scan.uf2
ht16k33_i2c.uf2
lcd_1602_i2c.uf2
lis3dh_i2c.uf2
mcp9808_i2c.uf2
mma8451_i2c.uf2
mpl3115a2_i2c.uf2
mpu6050_i2c.uf2
pa1010d_i2c.uf2
pcf8523_i2c.uf2
slave_mem_i2c.uf2
slave_mem_i2c_burst.uf2
ssd1306_i2c.uf2
hello_interp.uf2
hello_multicore.uf2
multicore_fifo_irqs.uf2
multicore_runner.uf2
multicore_runner_queue.uf2
picow_bt_example_a2dp_sink_demo_background.uf2
picow_bt_example_a2dp_source_demo_background.uf2
picow_bt_example_gap_inquiry_background.uf2
picow_bt_example_gap_le_advertisements_background.uf2
picow_bt_example_gatt_counter_background.uf2
picow_bt_example_gatt_counter_with_wifi_background.uf2
picow_bt_example_gatt_heart_rate_client_background.uf2
picow_bt_example_gatt_streamer_server_background.uf2
picow_bt_example_gatt_streamer_server_with_wifi_background.uf2
picow_bt_example_hid_host_demo_background.uf2
picow_bt_example_hid_keyboard_demo_background.uf2
picow_bt_example_hid_mouse_demo_background.uf2
picow_bt_example_hog_host_demo_background.uf2
picow_bt_example_hog_keyboard_demo_background.uf2
picow_bt_example_hog_mouse_demo_background.uf2
picow_bt_example_pan_lwip_http_server_background.uf2
picow_bt_example_pbap_client_demo_background.uf2
picow_bt_example_sm_pairing_central_background.uf2
picow_bt_example_sm_pairing_peripheral_background.uf2
picow_bt_example_spp_counter_background.uf2
picow_bt_example_spp_streamer_background.uf2
picow_bt_example_spp_streamer_client_background.uf2
picow_ble_temp_reader.uf2
picow_ble_temp_sensor.uf2
picow_ble_temp_sensor_with_wifi.uf2
picow_access_point_background.uf2
picow_access_point_poll.uf2
picow_blink.uf2
picow_blink_fast_clock.uf2
picow_blink_slow_clock.uf2
picow_http_client.uf2
picow_http_client_verify.uf2
picow_httpd_background.uf2
picow_iperf_server_background.uf2
picow_iperf_server_poll.uf2
picow_ntp_client_background.uf2
picow_ntp_client_poll.uf2
picow_tcpip_server_background.uf2
picow_tcpip_server_poll.uf2
picow_tls_client_background.uf2
picow_tls_client_poll.uf2
picow_tls_verify_background.uf2
picow_udp_beacon_background.uf2
picow_udp_beacon_poll.uf2
picow_wifi_scan_background.uf2
picow_wifi_scan_poll.uf2
picoboard_blinky.uf2
picoboard_button.uf2
pio_addition.uf2
pio_apa102.uf2
pio_clocked_input.uf2
pio_differential_manchester.uf2
hello_pio.uf2
pio_hub75.uf2
pio_i2c_bus_scan.uf2
pio_ir_loopback.uf2
pio_logic_analyser.uf2
pio_manchester_encoding.uf2
pio_onewire.uf2
pio_blink.uf2
pio_pwm.uf2
pio_quadrature_encoder.uf2
pio_quadrature_encoder_substep.uf2
pio_spi_flash.uf2
pio_spi_loopback.uf2
pio_squarewave.uf2
pio_squarewave_div_sync.uf2
pio_st7789_lcd.uf2
uart_pio_dma.uf2
pio_uart_rx.uf2
pio_uart_rx_intr.uf2
pio_uart_tx.uf2
pio_ws2812.uf2
pio_ws2812_parallel.uf2
hello_pwm.uf2
pwm_led_fade.uf2
pwm_measure_duty_cycle.uf2
hello_reset.uf2
hello_rtc.uf2
rtc_alarm.uf2
rtc_alarm_repeat.uf2
bme280_spi.uf2
max7219_32x8_spi.uf2
max7219_8x7seg_spi.uf2
mpu9250_spi.uf2
spi_dma.uf2
spi_flash.uf2
spi_master.uf2
spi_slave.uf2
hello_double_tap.uf2
narrow_io_write.uf2
rand.uf2
unique_board_id.uf2
hello_timer.uf2
periodic_sampler.uf2
timer_lowlevel.uf2
hello_uart.uf2
lcd_uart.uf2
uart_advanced.uf2
dev_hid_composite.uf2
dev_lowlevel.uf2
dev_multi_cdc.uf2
tinyusb_dev_audio_4_channel_mic.uf2
tinyusb_dev_audio_test.uf2
tinyusb_dev_audio_test_multi_rate.uf2
tinyusb_dev_board_test.uf2
tinyusb_dev_cdc_dual_ports.uf2
tinyusb_dev_cdc_msc.uf2
tinyusb_dev_cdc_uac2.uf2
tinyusb_dev_dfu.uf2
tinyusb_dev_dfu_runtime.uf2
tinyusb_dev_dynamic_configuration.uf2
tinyusb_dev_hid_boot_interface.uf2
tinyusb_dev_hid_composite.uf2
tinyusb_dev_hid_generic_inout.uf2
tinyusb_dev_hid_multiple_interface.uf2
tinyusb_dev_midi_test.uf2
tinyusb_dev_msc_dual_lun.uf2
tinyusb_dev_net_lwip_webserver.uf2
tinyusb_dev_uac2_headset.uf2
tinyusb_dev_uac2_speaker_fb.uf2
tinyusb_dev_usbtmc.uf2
tinyusb_dev_video_capture.uf2
tinyusb_dev_video_capture_2ch.uf2
tinyusb_dev_webusb_serial.uf2
host_cdc_msc_hid.uf2
tinyusb_host_bare_api.uf2
tinyusb_host_cdc_msc_hid.uf2
tinyusb_host_device_info.uf2
tinyusb_host_hid_controller.uf2
tinyusb_host_msc_file_explorer.uf2
hello_watchdog.uf2
blink.uf2
hello_serial.uf2
hello_usb.uf2
ができる。
□□□□□□□□□□
Micrpython を使う。
USB port ==================================================> PICO-W USB port
PICO-WのUSBケーブルをボードのSWを押しながら差し込む。
表示されたマスストレージデバイスに
~/pico/pico/micropython/ports/rp2/build-RPI_PICO_W/firmware.uf2 ファイルをドラッグコピーする。
ファイル名が消えたら書き込まれたことになる。
配線を以下のようにする。
+------------------+
USB port ===| Debug Probe (U)-+---------------オレンジ----> PICO-W GPIO-1(RX UART) pin2
| (D) | D 未接続 イエロー----> PICO-W GPIO-0(TX UART) pin1
+------------------+ ブラック----> PICO-W GND pin3
USB port ==================================================> PICO-W USB port
$ sudo apt install minicom
PICO-W側のUSBケーブルを接続。
$ minicom -o -D /dev/ttyACM0
改行入力
>>> from machine import UART, Pin
>>> uart0 = UART(0,baudrate=115200, tx=Pin(0), rx=Pin(1))
>>> tsData= b'Hello world!!\r\n'
デバッグプローブのUSBケーブルを接続。
別端末ウィンドウより、
$ minicom -o -D /dev/ttyACM1
次にプログラム入力中ウィドウに以下を入力する。
>>> uart0.write(tsData)
デバッグプローブ側のウィンドウに"Hello world!!"が表示される。
>>> help('modules')
__main__ asyncio/__init__ hashlib rp2
_asyncio asyncio/core heapq select
_boot asyncio/event io socket
_boot_fat asyncio/funcs json ssl
_onewire asyncio/lock lwip struct
_rp2 asyncio/stream machine sys
_thread binascii math time
_webrepl bluetooth micropython tls
aioble/__init__ builtins mip/__init__ uasyncio
aioble/central cmath neopixel uctypes
aioble/client collections network urequests
aioble/core cryptolib ntptime vfs
aioble/device deflate onewire webrepl
aioble/l2cap dht os webrepl_setup
aioble/peripheral ds18x20 platform websocket
aioble/security errno random
aioble/server framebuf re
array gc requests/__init__
Plus any modules on the filesystem
>>> print(rp2.country())
JP
>>> import machine
>>> led = machine.Pin("LED", machine.Pin.OUT)
>>> led.on() # PICO-Wボード緑LED点灯
>>> led.off() # PICO-Wボード緑LED消灯
>>> import sys
>>> sys.implementation
(name='micropython', version=(1, 25, 0, 'preview'), _machine='Raspberry Pi Pico W with RP2040', _mpy=4870, _build='RPI_PICO_W')
2023-09-21 「ENC28J60 LANアダプタ Micropython WEB Serverプログラム」
参考:日経LINUX 2017年4月号 Zero用のHAT風ボード イーサネットなどを実装 p-60 ~ 65
http://www.picfun.com/ENC28J60frame.html
デモプログラムを自作基板で動かす
https://www.olimex.com/Products/Modules/Ethernet/MOD-ENC28J60/
"ATMega32 example - ATMega32 and ENC28J60-H - written by Erik Rasmussen" In Right Window
https://www.olimex.com/Products/Modules/Ethernet/ENC28J60-H/resources/Webserver_ATMega32_ENC28J60-H.zip
ENC28J60 LANアダプタを使ってC言語で作成された
WEBサーバー"ATMega32 example - ATMega32 and ENC28J60-H - written by Erik Rasmussen"を
Raspberry pi PICO のMicropythonに書き換えてみた。
回路:
"ENC28J60 LANアダプタ PYTHONプログラム"で使った基板を使う。
PHY機能動作中にエラーがあると、SPIコマンドRESETではPHY機能をRESETできないので
GP-22と基板RESETを接続し、プログラムでハードリセット実行可能。
配線:
LANボード RaspberryPI PICO
3.3V ------------- 3.3V OUT
GND ------------- GND
INT ------------- GP 21
CS ------------- GP 17
SI ------------- GP 19
SO ------------- GP 16
SCK ------------- GP 18
RESET ------------- GP 22
実行:
$ thonny enc28j60.py
----
..... Init() Exit .....
. HwRevID: 0x04
. Cntrl: ECON1 ECON2 ESTAT EIR EIE
. 0x04 0x80 0x01 0x00 0xC0
. MAC : MACON1 MACON3 MACON4
. 0x0D 0x32 0x00
. Rx : ERXST ERXND ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL
. 0x0000 0x19FE 0x0000 0x0000 0xB0 0x00 0x05DC
. Tx : ETXST ETXND MACLCON1 MACLCON2 MAPHSUP
. 0x19FF 0x1FFF 0x0F 0x37 0x10
..........
My MAC Adrress: b'3e:3f:3f:02:11:22'
------ PHY Register ------
- PHCON1:0000
- PHCON2:0100
- PHSTAT1:1804
- PHSTAT2:0400
- PHID1:0083
- PHID2:1400
------------
Link UP
Link UP
Link UP
Recv: 60 ,Data= b'3e 3f 3f 02 11 22 xx xx xx xx ed d5 08 06 00 01 08 00 06 04 00 02 xx xx xx xx ed d5 c0 a8 01 01 3e 3f 3f 02 11 22 c0 a8 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
1 Sec ..
Recv: 60 ,Data= b'3e 3f 3f 02 11 22 xx xx xx xx ed d5 08 06 00 01 08 00 06 04 00 01 xx xx xx xx ed d5 c0 a8 01 01 3e 3f 3f 02 11 22 c0 a8 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
2 Sec ..
Recv: 60 ,Data= b'3e 3f 3f 02 11 22 xx xx xx xx ed d5 08 06 00 01 08 00 06 04 00 01 xx xx xx xx ed d5 c0 a8 01 01 3e 3f 3f 02 11 22 c0 a8 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
3 Sec ..
4 Sec ..
Recv: 60 ,Data= b'3e 3f 3f 02 11 22 xx xx xx xx ed d5 08 06 00 01 08 00 06 04 00 01 xx xx xx xx ed d5 c0 a8 01 01 3e 3f 3f 02 11 22 c0 a8 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
Recv: 60 ,Data= b'ff ff ff ff ff ff xx xx xx xx ed d5 08 06 00 01 08 00 06 04 00 01 xx xx xx xx ed d5 c0 a8 01 01 00 00 00 00 00 00 c0 a8 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
5 Sec ..
6 Sec ..
Recv: 60 ,Data= b'ff ff ff ff ff ff xx xx xx xx ed d5 08 06 00 01 08 00 06 04 00 01 xx xx xx xx ed d5 c0 a8 01 01 00 00 00 00 00 00 c0 a8 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
Recv: 60 ,Data= b'ff ff ff ff ff ff xx xx xx xx ed d5 08 06 00 01 08 00 06 04 00 01 xx xx xx xx ed d5 c0 a8 01 01 00 00 00 00 00 00 c0 a8 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
7 Sec ..
8 Sec ..
9 Sec ..
10 Sec ..
11 Sec ..
12 Sec ..
13 Sec ..
14 Sec ..
15 Sec ..
---
WEBサーバーは実行前に、enc28j60.py, net.pyをRaspberry pi PICOメモリに書き込んでおく。
$ thonny websrv.py
---
..... Init() Exit .....
. HwRevID: 0x04
. Cntrl: ECON1 ECON2 ESTAT EIR EIE
. 0x04 0x80 0x01 0x00 0xC0
. MAC : MACON1 MACON3 MACON4
. 0x0D 0x32 0x00
. Rx : ERXST ERXND ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL
. 0x0000 0x19FE 0x0000 0x0000 0xB0 0x00 0x05DC
. Tx : ETXST ETXND MACLCON1 MACLCON2 MAPHSUP
. 0x19FF 0x1FFF 0x0F 0x37 0x10
..........
---
WEBブラウザで http://192.168.1.39:8080 で見る。
"Set Blue","Set Green", "Set Red", "Clear Color" をクリックすると丸の色が変わる。
プログラム:
[micro-py-enc28j60-web-srv.zip]
2023-09-07 「ENC28J60 LANアダプタ PYTHONプログラム」
参考:日経LINUX 2017年4月号 Zero用のHAT風ボード イーサネットなどを実装 p-60 ~ 65
http://www.picfun.com/ENC28J60frame.html
デモプログラムを自作基板で動かす
From https://github.com/przemobe/micropy-ENC28J60.git
ENC28J60でLAN基板を作って、PYTHONで制御してみた。
まず、SPIインターフェースを有効にする。dtoverlayは設定しない。
もとのプログラムは https://github.com/przemobe/micropy-ENC28J60.git MICROPYTONのプログラムをPYTHON3に書換えました。
回路:
PHY機能動作中にエラーがあると、SPIコマンドRESETではPHY機能をRESETできないので
GPIO24と基板RESETを接続し、PYTHONプログラムでハードリセット実行を可能にしました。
配線:
LANボード RaspberryPI
3.3V ------------- 3.3V
GND ------------- GND
INT ------------- GPIO 25
SCS ------------- GPIO 8 / CE0
MOSI ------------- GPIO 10
MISO ------------- GPIO 9
SCLK ------------- GPIO 11
RESET ------------- GPIO 24
実行:
$ python enc28j60.py
---
My MAC Adrress: b'3e:3f:3f:02:11:22'
..... INIT() exit .....
. HwRevID: 0x04
. Cntrl: ECON1 ECON2 ESTAT EIR EIE
. 0x04 0x80 0x01 0x00 0xD0
. MAC : MACON1 MACON3 MACON4
. 0x0D 0xB3 0x40
. Rx : ERXST ERXND ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL
. 0x0000 0x17FF 0x0000 0x17FF 0xA1 0x00 0x05EE
. Tx : ETXST ETXND MACLCON1 MACLCON2 MAPHSUP
. 0x1800 0x1800 0x0F 0x37 0x10
..........
Link UP
Link UP
Link UP
------ PHY Register ------
- PHCON1:0100
- PHCON2:0100
- PHSTAT1:1804
- PHSTAT2:0600
- PHID1:0083
- PHID2:1400
------------
1 Sec ..
Recv: 60 ,Data= b'3e 3f 3f 02 11 22 XX XX XX X6 ed d5 08 06 00 01 08 00 06 04 00 02 XX XX XX X6 ed d5 c0 a8 01 01 3e 3f 3f 02 11 22 c0 a8 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
Recv: 60 ,Data= b'3e 3f 3f 02 11 22 XX XX XX X6 ed d5 08 06 00 01 08 00 06 04 00 01 XX XX XX X6 ed d5 c0 a8 01 01 3e 3f 3f 02 11 22 c0 a8 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
2 Sec ..
Recv: 60 ,Data= b'3e 3f 3f 02 11 22 XX XX XX X6 ed d5 08 06 00 01 08 00 06 04 00 01 XX XX XX X6 ed d5 c0 a8 01 01 3e 3f 3f 02 11 22 c0 a8 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
3 Sec ..
Recv: 60 ,Data= b'3e 3f 3f 02 11 22 XX XX XX X6 ed d5 08 06 00 01 08 00 06 04 00 01 XX XX XX X6 ed d5 c0 a8 01 01 3e 3f 3f 02 11 22 c0 a8 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
4 Sec ..
Recv: 60 ,Data= b'ff ff ff ff ff ff XX XX XX X6 ed d5 08 06 00 01 08 00 06 04 00 01 XX XX XX X6 ed d5 c0 a8 01 01 00 00 00 00 00 00 c0 a8 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
5 Sec ..
Recv: 60 ,Data= b'ff ff ff ff ff ff XX XX XX X6 ed d5 08 06 00 01 08 00 06 04 00 01 XX XX XX X6 ed d5 c0 a8 01 01 00 00 00 00 00 00 c0 a8 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
6 Sec ..
Recv: 60 ,Data= b'ff ff ff ff ff ff XX XX XX X6 ed d5 08 06 00 01 08 00 06 04 00 01 XX XX XX X6 ed d5 c0 a8 01 01 00 00 00 00 00 00 c0 a8 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
7 Sec ..
8 Sec ..
9 Sec ..
10 Sec ..
11 Sec ..
12 Sec ..
13 Sec ..
14 Sec ..
15 Sec ..
---
$ python sntp.py
---
..... INIT() exit .....
. HwRevID: 0x04
. Cntrl: ECON1 ECON2 ESTAT EIR EIE
. 0x04 0x80 0x01 0x00 0xD0
. MAC : MACON1 MACON3 MACON4
. 0x0D 0xB3 0x40
. Rx : ERXST ERXND ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL
. 0x0000 0x17FF 0x0000 0x17FF 0xA1 0x00 0x05EE
. Tx : ETXST ETXND MACLCON1 MACLCON2 MAPHSUP
. 0x1800 0x1800 0x0F 0x37 0x10
..........
MAC ADDR: 3e:3f:3f:02:12:34
ENC28J60 revision ID: 0x04
[SNTP] Connecting...
ARP Request= b'ff ff ff ff ff ff 3e 3f 3f 02 12 34 08 06 00 01 08 00 06 04 00 01 3e 3f 3f 02 12 34 c0 a8 01 27 00 00 00 00 00 00 c0 a8 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
RECV= b'3e 3f 3f 02 12 34 XX xX XX X6 ed d5 08 06 00 01 08 00 06 04 00 02 XX xX XX X6 ed d5 c0 a8 01 01 3e 3f 3f 02 12 34 c0 a8 01 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
Rx ARP oper=2
ARP Register: 192.168.1.1 is at XX:XX:XX:X6:ED:D5
[SNTP] Connected
SNTP Request= b'1b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
SEND NTP request: b'XX xX XX X6 ed d5 3e 3f 3f 02 12 34 08 00 45 00 00 4c 00 00 00 00 80 11 0e 31 c0 a8 01 27 a2 9f c8 01 1f bb 00 7b 00 38 97 d7 1b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
RECV= b'3e 3f 3f 02 12 34 XX xX XX X6 ed d5 08 00 45 00 00 4c 7f bb 40 00 38 11 96 75 a2 9f c8 01 c0 a8 01 27 00 7b 1f bb 00 38 1f da 1c 03 00 e7 00 00 21 70 00 00 00 2f 0a 98 08 05 e8 9c 74 55 70 d5 43 24 00 00 00 00 00 00 00 00 e8 9c 74 a3 02 c4 c5 97 e8 9c 74 a3 02 c9 ab 45'
Rx my IP proto=17
[SNTP] Response received: time= 2023-09-01 23:33:07 (JST)
---
プログラム:
[python-enc28j60.zip]
2023-09-07 「抵抗−2RラダーDAC」
参考:トランジスタ技術 2001年3月号 P-343~347
Microchip SPI 16bit Expander MCP23S17 を使って抵抗ラダーDACを作ってみた。
回路:
配線:
DACボード RaspberryPI
5V ------------- 5V
GND ------------- GND
CS ------------- GPIO 8 / CE0
SI ------------- GPIO 10
SO ------------- GPIO 9
CLK ------------- GPIO 11
プログラム:
参照: https://hw101.tbs1.de/mcp23s17/
MCP23S17 I/O Expander
Ansteuerungen grundlegender Hardwarebausteine
$ nano MCP23S17.py
---
import spidev
class MCP23S17:
def __init__(self, slave_address, busnumber, chipnumber):
assert busnumber in [0, 1]
assert chipnumber in [0, 1]
self.controlbyte_write = 0x40 |(slave_address<<1) # <<==修正
self.controlbyte_read = 0x40 |((slave_address<<1)+1) # <<==修正
self.spi = spidev.SpiDev()
self.spi.open(busnumber, chipnumber)
self.spi.max_speed_hz = 10000000
# configure default registers
self._regs = {'conf': {'A': 0x00, 'B': 0x01},
'input': {'A': 0x12, 'B': 0x13},
'output': {'A': 0x14, 'B': 0x15}}
def write_config(self, portab, value):
assert portab in ['A', 'B']
reg = self._regs['conf'][portab]
self.spi.xfer([self.controlbyte_write, reg, value])
def read_config(self, portab):
assert portab in ['A', 'B']
reg = self._regs['conf'][portab]
return self.spi.xfer([self.controlbyte_read, reg, 0])[2]
def write_output(self, portab, value):
assert portab in ['A', 'B']
reg = self._regs['output'][portab]
self.spi.xfer([self.controlbyte_write, reg, value])
def read_output(self, portab):
assert portab in ['A', 'B']
reg = self._regs['output'][portab]
return self.spi.xfer([self.controlbyte_read, reg, 0])[2]
def read_input(self, portab):
assert portab in ['A', 'B']
reg = self._regs['input'][portab]
return self.spi.xfer([self.controlbyte_read, reg, 0])[2]
---
$ nano macp23s1.py
---
import MCP23S17
import time
import math
mcp = MCP23S17.MCP23S17(0,0,0)
mcp.write_config('A',0x00)
mcp.write_config('B',0x00)
mcp.write_output('A',0x00)
mcp.write_output('B',0x00)
while 1:
for d in range(256):
mcp.write_output('A',d)
mcp.write_output('B',d)
time.sleep(0.5)
---
0〜255の変換。
$ nano mcp23s2.py
---
import MCP23S17
import time
import math
mcp = MCP23S17.MCP23S17(0,0,0)
mcp.write_config('A',0x00)
mcp.write_config('B',0x00)
mcp.write_output('A',0x00)
mcp.write_output('B',0x00)
while 1:
for d in range(0, 360, 5):
s = math.sin( (math.pi * d) / 180.0 ) + 1.0
a = int(s * 127)
mcp.write_output('A',a & 0xFF)
mcp.write_output('B',a & 0xFF)
#time.sleep(0.01)
---
sin波形出力。
2023-07-12 「Raspberry Pi Bullseye OS にCAN ボード追加」
参考:(1)https://www.beyondlogic.org/adding-can-controller-area-network-to-the-raspberry-pi/
Adding CAN to the Raspberry PI
(2)https://qiita.com/suzutsuki0220/items/8642b1c3ea51859a95ad
Raspberry PiでOBD-II (CAN)の情報を取得するための基板を自作する
(3)https://westgate-lab.hatenablog.com/entry/2021/08/15/183000
RaspberryPiでCAN通信(ドーターボード回路図付き)
(4)http://reclearnengoolong.blog.fc2.com/blog-entry-1161.html
動かして学ぶCAN通信(12)
(5)https://stackoverflow.com/questions/73080694/how-to-install-a-rx-callback-with-python-can
How to install a rx callback with python-can?
(6)python-can PDFドキュメント Release 4.2.2 (Jun 30, 2023)
RasPi PICOに使ったCAN基板を使う。
OS はBullseye arm32 で設定。
配線:
CAN基板 Ras PI
CS --------- GPIO 8
SO --------- GPIO 9
SI --------- GPIO 10
SCK --------- GPIO 11
INT --------- GPIO 25
VCC --------- 3.3V
GND --------- GND
J1 ショート
設定:
$ sudo nano /boot/config.txt
---
dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=8000000,interrupt=25
---追加
動作確認:
$ sudo reboot
$ ip a
か
$ ifconfig
can0 があればよい
$ sudo apt install can-utils
$ sudo ip link set can0 type can bitrate 500000 loopback on
$ sudo ip link set can0 up
$ candump can0 -x
別の端末WINDOWで
$ cansend can0 123#12345678
candumpのWINDOWで送受信データが出ればOK.
$ sudo nano /etc/network/interfaces.d/can0.conf
----
auto can0
iface can0 inet manual
pre-up /sbin/ip link set can0 type can bitrate 500000
up /sbin/ip link set can0 up
down /sbin/ip link set can0 down
---作成
$ sudo reboot
Raspberry PiのMCP2515 CAN基板 と Raspberry Pi PICO のMCP2515 CAN基板を2線で接続する。
実行:
Raspberry Pi PICO側: Raspberry Pi Bullseye OS側
Thonny で MCP5215.py を実行する。 端末1 $ candump -x cano
端末2 $ cansend can0 123#12
シェル: recv: ['0x12'] 表示 端末1に can0 TX - - 123 [1] 12
can0 RX - - 156 [4] 01 等が表示
となるところなのだが、PICO側MCP2515.pyの設定では反応がない。
CAN 500KBPS となっていないかもしれないので設定を調べる。
can CNF1,CNF2,CNF3を調べる
***************
mcp251x.c を 使ってCNF設定を調べる。
ビットタイミングの設定値はドライバーの別モジュールで計算されたものがlink upでmcp2515ドライバーに
渡される。
手順:
https://www.raspberrypi.org/documentation/linux/kernel/building.md
のLocal building のソースプログラム取得より
$ git clone --depth=1 https://github.com/raspberrypi/linux
ダウンロードされたら
linux/drivers/net/can/spi/mcp251x.c をコピーする。
$ sudo apt install git bc bison flex libssl-dev make
ほぼインストールされていると思うが。
$ nano Makefile
---
obj-m:=mcp251x.o
all:
make -C /lib/modules/$(shell uname -r)/build M=${PWD} CFLAGS_$(obj-m)="-DDEBUG" modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=${PWD} clean
install:
rm -f mcp251x.ko.xz
xz mcp251x.ko
cp mcp251x.ko.xz /lib/modules/$(shell uname -r)/kernel/drivers/net/can/spi/
---作成
.xzのファイルでないとモジュールがロードされない。
CFLAGS_$(obj-m)="-DDEBUG" でdev_dbg()が有効となってdmesgでCNFの内容がわかる。
$ make
$ sudo make install
$ sudo reboot
/boot/config.txt のdtoverlayは設定済のこと。
設定調査手順:
sudo ip link set can0 down
sudo ip link set can0 type can bitrate 125000
800KBPS以上は設定できないとなる。
/bbo/config.txt の dtoverlay設定でXtal周波数がもっと高ければ,
なんて仮定したらどうなるかは dtoverlay設定でXtal周波数を高くして定義して
やってみるとOKとなる。
もっと早いボーレートの場合は、もっと高いXtal周波数でないとだめ。
sudo ip link set can0 up
これでMCP2515 のCNF1,CNF2,CNF3が設定される。
600KBPSでワーニングが出る。
mcp251x spi0.0 can0: bitrate error 4.7%
mcp251x spi0.0: CNF: 0x00 0x89 0x01
dmesg | tail
ーーー
CNF1 CNF2 CNF3
500KBPS 0x00 0x91 0x01
250KBPS 0x00 0xB5 0x01
125KBPS 0x01 0xB5 0x01
100KBPS 0x01 0xBF 0x02
PYTHONプログラム:
相手はPICO側のプログラムを実行する。
ビットボーレートは設定してあるもの(/etc/network/interfaces.d/can0.conf)で実行される。
$ sudo apt install python3-can
CANモジュールインストール
$ nano can.py
---
import os
import can
import time
def print_message(msg) -> None:
if msg.is_error_frame is False:
print('ID:',hex(msg.arbitration_id), ' DATA:', msg.data.hex() )
else:
print("Error recv()")
filter = [
{"can_id": 0x156, "can_mask": 0x7FF, "extended": False},
]
can0 = can.interface.Bus(channel = 'can0', bustype = 'socketcan', can_filters=filter) # socketcan_native
n = 0
smsg = [0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80]
notifier = can.Notifier(can0, [print_message])
try:
while True:
msg = can.Message(arbitration_id=0x123, data=smsg[n%8:], is_extended_id=False)
try:
can0.send(msg, timeout=3.0) # ID:0x156 ==> ID:0x123
except Exception as e:
print("Error send()")
n += 1
time.sleep(0.5)
except KeyboardInterrupt:
print('')
notifier.stop()
can0.shutdown()
--作成
フィルター設定があるので指定IDしか受信しない。
$ python can.py
PICO ThonnyでCANプログラム実行
--- 結果---
Error recv()
Error recv()
ID: 0x156 DATA: 0102030405060708
ID: 0x156 DATA: 01
ID: 0x156 DATA: 0102
ID: 0x156 DATA: 010203
ID: 0x156 DATA: 01020304
ID: 0x156 DATA: 0102030405
ID: 0x156 DATA: 010203040506
ID: 0x156 DATA: 01020304050607
ID: 0x156 DATA: 0102030405060708
ID: 0x156 DATA: 01
ID: 0x156 DATA: 0102
ID: 0x156 DATA: 010203
ID: 0x156 DATA: 01020304
ID: 0x156 DATA: 0102030405
---PICO側シェル 結果---
...
init...
send data...
0x123 ['0x30', '0x40', '0x50', '0x60', '0x70', '0x80']
0x123 ['0x40', '0x50', '0x60', '0x70', '0x80']
0x123 ['0x50', '0x60', '0x70', '0x80']
0x123 ['0x60', '0x70', '0x80']
0x123 ['0x70', '0x80']
0x123 ['0x80']
0x123 ['0x10', '0x20', '0x30', '0x40', '0x50', '0x60', '0x70', '0x80']
0x123 ['0x20', '0x30', '0x40', '0x50', '0x60', '0x70', '0x80']
0x123 ['0x30', '0x40', '0x50', '0x60', '0x70', '0x80']
0x123 ['0x40', '0x50', '0x60', '0x70', '0x80']
0x123 ['0x50', '0x60', '0x70', '0x80']
2023-07-12 「Raspberry Pi PICO CAN 通信」
PICOでCAN通信ができるかやってみた。
使ったのはamazon で買った「MCP2515 CAN バス モジュール TJA1050 SPI レシーバー」3個セット。
参考:https://www.waveshare.com/wiki/Pico-CAN-B
WIKI Pico-CAN-B
を参考にmicropython 上でWIKI Pico-CAN-B にあるPYTHONサンプルを使用した。
配線:
CAN基板 PICO
VCC -------- 3.3V OUT
GND -------- GND
CS -------- GP5
SO -------- GP4
SI -------- GP7
SCK -------- GP6
INT -------- GP21
J1 ショート 終端抵抗あり
CAN-H ------- CAN-H
CAN-L ------- CAN-L
プログラム:
サンプルプログラムは、IDが何でも受信するようになっているのでそれをID一致に修正した。
$ nano MCP5215.py
---
from machine import Pin,SPI
import time
# Config Reg
CANSTAT = 0x0E
CANCTRL = 0x0F
BFPCTRL = 0x0C
CNF3 = 0x28
CNF2 = 0x29
CNF1 = 0x2A
CANINTE = 0x2B
CANINTF = 0x2C
EFLG = 0x2D
TXRTSCTRL = 0x0D
# Recieve Filters
RXF0SIDH = 0x00
RXF0SIDL = 0x01
RXF0EID8 = 0x02
RXF0EID0 = 0x03
# Receive Masks
RXM0SIDH = 0x20
RXM0SIDL = 0x21
RXM0EID8 = 0x22
RXM0EID0 = 0x23
# Tx Buffer 0
TXB0CTRL = 0x30
TXB0SIDH = 0x31
TXB0SIDL = 0x32
TXB0EID8 = 0x33
TXB0EID0 = 0x34
TXB0DLC = 0x35
TXB0D0 = 0x36
TXB0D1 = 0x37
TXB0D2 = 0x38
TXB0D3 = 0x39
TXB0D4 = 0x3A
TXB0D5 = 0x3B
TXB0D6 = 0x3C
TXB0D7 = 0x3D
# Rx Buffer 0
RXB0CTRL = 0x60
RXB0SIDH = 0x61
RXB0SIDL = 0x62
RXB0EID8 = 0x63
RXB0EID0 = 0x64
RXB0DLC = 0x65
RXB0D0 = 0x66
RXB0D1 = 0x67
RXB0D2 = 0x68
RXB0D3 = 0x69
RXB0D4 = 0x6A
RXB0D5 = 0x6B
RXB0D6 = 0x6C
RXB0D7 = 0x6D
# CANCTRL
REQOP_CONFIG = 0x80
REQOP_LISTEN = 0x60
REQOP_LOOPBACK =0x40
REQOP_SLEEP = 0x20
REQOP_NORMAL = 0x00
ABORT = 0x10
# CANSTAT
OPMODE_CONFIG= 0x80
OPMODE_LISTEN= 0x60
OPMODE_LOOPBACK =0x40
OPMODE_SLEEP = 0x20
OPMODE_NORMAL= 0x00
# CAN Command
CAN_RESET = 0xC0
CAN_READ = 0x03
CAN_WRITE = 0x02
CAN_RTS = 0x80
CAN_RTS_TXB0 = 0x81
CAN_RTS_TXB1 = 0x82
CAN_RTS_TXB2 = 0x84
CAN_RATE = { # 8MHz Xtal
"5KBPS" : [0x31, 0XB5, 0x01],
"10KBPS" : [0x18, 0XB5, 0X01],
"20KBPS" : [0x09, 0XBF, 0x02],
"50KBPS" : [0x04, 0XB5, 0x01],
"100KBPS" : [0x01, 0xBF, 0x02],
"125KBPS" : [0x01, 0xB5, 0x01],
"250KBPS" : [0x00, 0xB5, 0x01],
"500KBPS" : [0x00, 0x91, 0x01],
}
class MCP2515():
def __init__(self, my_id=0, intPin=21):
self.intPin = intPin
self.my_id = my_id
self.SPI0_CS0 = 5
self.spi = SPI(0)
self.spi = SPI(0,10000_000)
self.spi = SPI(0,10000_000,polarity=0, phase=0,sck=Pin(6),mosi=Pin(7),miso=Pin(4))
self.cs = Pin(self.SPI0_CS0,Pin.OUT)
def ReadByte(self, addr):
self.cs(0)
self.spi.write(bytearray([CAN_READ]))
self.spi.write(bytearray([addr]))
res = self.spi.read(1)
self.cs(1)
return int.from_bytes(res,'big')
def WriteByte(self, addr):
self.cs(0)
self.spi.write(bytearray([addr]))
self.cs(1)
def WriteBytes(self, addr, data):
self.cs(0)
self.spi.write(bytearray([CAN_WRITE]))
self.spi.write(bytearray([addr]))
self.spi.write(bytearray([data]))
self.cs(1)
def Reset(self):
self.cs(0)
self.spi.write(bytearray([CAN_RESET]))
self.cs(1)
def Init(self, speed="500KBPS"):
self.Reset()
time.sleep(0.1)
self.WriteBytes(CNF1, CAN_RATE[speed][0])
self.WriteBytes(CNF2, CAN_RATE[speed][1])
self.WriteBytes(CNF3, CAN_RATE[speed][2])
self.WriteBytes(TXB0SIDH,0xFF)
self.WriteBytes(TXB0SIDL,0xE0)
self.WriteBytes(TXB0DLC, 0)
self.WriteBytes(RXB0SIDH,0x00)
self.WriteBytes(RXB0SIDL,0x60)
self.WriteBytes(RXB0CTRL,0x00) # match id
self.WriteBytes(RXB0DLC, 0)
self.WriteBytes(RXF0SIDH,(self.my_id>>3)&0xFF)
self.WriteBytes(RXF0SIDL,(self.my_id&0x07)<<5)
self.WriteBytes(RXM0SIDH,0xFF)
self.WriteBytes(RXM0SIDL,0xE0)
self.WriteBytes(CANINTF,0x00) # clean interrupt flag
self.WriteBytes(CANINTE,0x00) # Recv Int
self.WriteBytes(CANCTRL, REQOP_NORMAL)
self.pInt = Pin(self.intPin, Pin.IN)
self.pInt.irq(trigger=Pin.IRQ_FALLING, handler=self.call_read)
self.WriteBytes(CANINTE,0x01) # Enabled Recv Interrupt
def Send(self, CAN_ID, CAN_TX_Buf, length1):
while (self.ReadByte(TXB0CTRL) & 0x08):
time.sleep(0.01) # Wait Tx Busy
self.WriteBytes(TXB0SIDH, (CAN_ID>>3)&0XFF)
self.WriteBytes(TXB0SIDL, (CAN_ID&0x07)<<5)
self.WriteBytes(TXB0EID8, 0)
self.WriteBytes(TXB0EID0, 0)
self.WriteBytes(TXB0DLC, length1)
for j in range(0, length1):
self.WriteBytes(TXB0D0+j,CAN_TX_Buf[j])
self.WriteBytes(TXB0CTRL, 0) # clean flag
self.WriteByte(CAN_RTS_TXB0)
def Receive(self):
CAN_RX_Buf = []
len = self.ReadByte(RXB0DLC)
for i in range(0, len):
CAN_RX_Buf.append(hex(self.ReadByte(RXB0D0+i)))
self.WriteBytes(CANINTF, 0)
rid = (self.ReadByte(RXB0SIDH)<<3)|((self.ReadByte(RXB0SIDL)>>5)&0x07) # clean
return [rid,CAN_RX_Buf]
def call_read(self, p):
msg = self.Receive()
print(hex(msg[0]), msg[1])
if __name__ == '__main__':
print("...")
To_id = 0x156
can = MCP2515(my_id=0x123)
print("init...")
can.Init(speed='500KBPS')
print("send data...")
data = [65, 66, 67, 68, 69, 70, 71, 72]
n = 0
try:
while(1):
can.Send(To_id, data, (n % 8) + 1)
n += 1
time.sleep(0.3)
except KeyboardInterrupt:
print("\n...")
---
実行:
...
init...
send data...
0x123 ['0x30', '0x40', '0x50', '0x60', '0x70', '0x80']
0x123 ['0x40', '0x50', '0x60', '0x70', '0x80']
0x123 ['0x50', '0x60', '0x70', '0x80']
0x123 ['0x60', '0x70', '0x80']
0x123 ['0x70', '0x80']
0x123 ['0x80']
0x123 ['0x10', '0x20', '0x30', '0x40', '0x50', '0x60', '0x70', '0x80']
0x123 ['0x20', '0x30', '0x40', '0x50', '0x60', '0x70', '0x80']
0x123 ['0x30', '0x40', '0x50', '0x60', '0x70', '0x80']
0x123 ['0x40', '0x50', '0x60', '0x70', '0x80']
0x123 ['0x50', '0x60', '0x70', '0x80']
0x123 ['0x60', '0x70', '0x80']
0x123 ['0x70', '0x80']
0x123 ['0x80']
0x123 ['0x10', '0x20', '0x30', '0x40', '0x50', '0x60', '0x70', '0x80']
0x123 ['0x20', '0x30', '0x40', '0x50', '0x60', '0x70', '0x80']
2023-06-29 「RasPI PICO LANケーブル接続」
Raspberry pi PICOにW5500 IC 基板でLANケーブルを接続する。
micropythonのW5500用のNetworkモジュールを追加したものを作成する。
https://rafaelaroca.wordpress.com/2022/02/13/building-micropython-for-the-raspberry-pi-pico-with-ethernet-and-webrepl-support/
Yet Another Technology Blog
Building MicroPython for the Raspberry Pi PICO with Ethernet and WebREPL support
の中の 「Ethernet and Raspberry Pi Pico」
を参考にする。
$ git clone https://github.com/rafaelaroca/RP2040-HAT-MicroPython
$ cd RP2040-HAT-MicroPython
$ git submodule add https://github.com/micropython/micropython-lib/
$ cmake CMakeLists.txt
$ cd libraries
$ make -C mpy-cross
$ cd ports/rp2
$ nano boards/manifest.py
---
freeze("$(PORT_DIR)/modules")
freeze("$(MPY_DIR)/drivers/onewire")
freeze("$(MPY_DIR)/drivers/dht", "dht.py")
include("$(MPY_DIR)/extmod/uasyncio/manifest.py")
include("$(MPY_DIR)/drivers/neopixel/manifest.py")
freeze("$(MPY_DIR)/tools", ("upip.py", "upip_utarfile.py"))
freeze("$(MPY_DIR)/drivers/display", "ssd1306.py")
include("$(MPY_DIR)/extmod/webrepl/manifest.py")
# Libraries from micropython-lib, include only if the library directory exists
if os.path.isdir(convert_path("$(MPY_LIB_DIR)")):
# file utilities
freeze("$(MPY_LIB_DIR)/micropython/upysh", "upysh.py")
# requests
freeze("$(MPY_LIB_DIR)/python-ecosys/urequests", "urequests.py")
freeze("$(MPY_LIB_DIR)/micropython/urllib.urequest", "urllib/urequest.py")
# umqtt
freeze("$(MPY_LIB_DIR)/micropython/umqtt.simple", "umqtt/simple.py")
freeze("$(MPY_LIB_DIR)/micropython/umqtt.robust", "umqtt/robust.py")
---修正
$ make
できた build-PICO/firmware.uf2 をPICOに書き込む。
配線:
GPIO16 ---- MISO W5500
GPIO17 ---- SCS W5500
GPIO18 ---- SCLK W5500
GPIO19 ---- MOSI W5500
GPIO20 ---- RST W5500
GPIO21 ---- INT W5500
3.3V ---- 3.3V W5500
GND ---- GND W5500
USB ---- Raspberry Pi USB
実行:
Thonny で RP2040-HAT-MicroPython-00/examples/HTTP/HTTP_Serverを開く。
ーーー
from usocket import socket
from machine import Pin,SPI
import network
import rp2
import time
led = Pin(25, Pin.OUT)
#W5x00 chip init
def w5x00_init():
spi=SPI(0,2_000_000, mosi=Pin(19),miso=Pin(16),sck=Pin(18))
nic = network.WIZNET5K(spi,Pin(17),Pin(20)) #spi,cs,reset pin
nic.ifconfig(('192.168.1.20','255.255.255.0','192.168.1.1','8.8.8.8'))
while not nic.isconnected():
time.sleep(1)
print(nic.regs())
def web_page():
if led.value()==1:
led_state="ON"
else:
led_state="OFF"
html = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Raspberry Pi Pico Web server - WIZnet W5100S</title>
</head>
<body>
<div align="center">
<H1>Raspberry Pi Pico Web server & WIZnet Ethernet HAT</H1>
<h2>Control LED</h2>
PICO LED state: <strong>""" + led_state + """</strong>
<p><a href="/?led=on"><button class="button">ON</button></a><br>
</p>
<p><a href="/?led=off"><button class="button button2">OFF</button></a><br>
</p>
</div>
</body>
</html>
"""
return html
def main():
w5x00_init()
s = socket()
s.bind(('192.168.1.20', 80))
s.listen(5)
while True:
conn, addr = s.accept()
print('Connect from %s' % str(addr))
request = conn.recv(1024)
request = str(request)
#print('Content = %s' % request)
led_on = request.find('/?led=on')
led_off = request.find('/?led=off')
if led_on == 6:
print("LED ON")
led.value(1)
if led_off == 6:
print("LED OFF")
led.value(0)
response = web_page()
conn.send('HTTP/1.1 200 OK\n')
conn.send('Connection: close\n\n')
conn.send(response)
time.sleep(0.1) # <<== 追加
conn.close()
if __name__ == "__main__":
main()
ーーー修正
DHCP IPアドレスは獲得できない。ifconfig()固定アドレスとなる。
実行する。
ブラウザでhttp://192.168.1.20 で LED ON/OFFボタンをクリックするとPICO基板のLEDが点灯・消灯する。
2023-06-24 「雑誌MabPi」
雑誌 The MagPi が issue 130 から、月末にアップロードされたが、次の月の15日にならないとPDF Freeダウンロード
できなくなった。
2023-08-07 「RasPI ZERO W5500、ENC29J60 LANアダプタ接続」
参考:日経LINUX 2017年4月号 Zero用のHAT風ボード イーサネットなどを実装 p-60 ~ 65
http://www.picfun.com/ENC28J60frame.html
デモプログラムを自作基板で動かす
ENC28J60でLAN基板を作ってみた。
ENC28J60はチップのREVSIONが4種類ある。
今回使うのを調べてみた。
まず、SPIインターフェースを有効にする。(まだ、dtoverlayは設定しない)
pythonプログラム
$ nano enc.py
---
import spidev
import time
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1200000
spi.xfer2([0xff]) # reset enc28j60
time.sleep(0.5)
spi.xfer2([0x9f,0x03]) # select enc28j60 banck 3
rev = spi.xfer2([0x12,0x00]) # read enc28j60 EREVID
print(rev[1]) # 4
spi.close()
---作成
$ python enc.py
...
4
...
EREVIP が4である。
回路:
配線:
LANボード RaspberryPI
3.3V ------------- 3.3V
GND ------------- GND
INT ------------- GPIO 25
CS ------------- GPIO 8 / CE0
SI ------------- GPIO 10
SO ------------- GPIO 9
SCLK ------------- GPIO 11
OS: 2023-05-03 arm32 bullseye Desctopイメージ
設定:
raspi-config SPI インターフェース ON
/boot/config.txt
------
dtoverlay=enc28j60,int=pin=25
-----追加
/etc/dhcpcd.conf
-----
interface eth0
static ip_address=192.168.1.5x/24
static routers=192.168.1.x
static domain_name_servers=192.168.1.x
-----追加(固定IPアドレス)
★★★★他のLAN基板↓↓
Raspberry pi ZERO (WIFIなし)にMicroChip ENC28J60を同様なLANカードを接続する。
W5500が実装されたボードがAMAZONで売られているので買ってやってみた。
Copuhgima W5500イーサネットネットワークモジュールハードウェア / IP 51 / St2
マイクロコントローラプログラムオーバー W5100
配線:
LANボード RaspberryPI
3.3V ------------- 3.3V
GND ------------- GND
INT ------------- GPIO 25
SCS ------------- GPIO 8 / CE0
MOSI ------------- GPIO 10
MISO ------------- GPIO 9
SCLK ------------- GPIO 11
5V NC
RST NC
OS: 2023-05-03 arm32 bullseye Desctopイメージ
.... osinfo ....
==== BOARD ( Memory 0.5MB ) ===
Raspberry Pi Zero Rev 1.3
======= OS ( 32 Bits ) ========
Raspbian GNU/Linux 11 (bullseye)
===============================
設定:
raspi-config SPI インターフェース ON
/boot/config.txt
------
dtoverlay=w5500,int=pin=25,speed=20000000
-----追加
/etc/dhcpcd.conf
-----
interface eth0
static ip_address=192.168.1.5x/24
static routers=192.168.1.x
static domain_name_servers=192.168.1.x
-----追加(固定IPアドレス)
DHCPでアドレスをふるようになってる場合はリブートするたびにアドレスが変わるので面倒な場合は
固定IPアドレスにするのがよい。(MACアドレスがランダムに自動割当される)
設定が終わったら、リブートする。
dtoverlayではW5500を指定するのですがlsmodするとw5100となっている。
2023-06-13 「octave GPIO」
google検索の途中にたまたま引っかかったのでやってみた。
大分前にやったことがあったが、今はGUIも付いて変わっている。
CPPで作った関数が使えるんだとのこと。
sudo apt install octave
sudo apt install liboctave-dev (実行ファイル mkoctfile)
wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.68.tar.gz
tar xzvf bcm2835-1.68.tar.gz
cd bcm2835-1.68/
./configure CFLAGS=-fPIC
make
sudo make install
cd ..
git clone https://github.com/gnu-octave/octave-rpi-gpio.git
cd octave-rpi-gpio
make
nano test_bcm2835oct.m
---
sleep(x) を pause(x) に修正。
---
LEDと抵抗を40ピン 26(GPIO-7) と 30(GND)に配線。
octave
端末でOCTAVE
>> test_bcm2835oct
test_bcm2835oct.m 実行。LEDが点滅する。
2023-06-25 「Raspberry Pi の小ワザ」
▲▲▲▲
PYTHONでファイルの種類を確認する。
・その1
sudo apt install python3-magic
>>> import magic
>>> f.from_file('345', mime=True)
'text/plain'
>>> f.from_file('pic01', mime=True)
'image/png'
・その2
>>> from subprocess import getoutput
>>> getoutput('file 345')
'345: UTF-8 Unicode text'
>>> getoutput('file pic01')
'pic01: PNG image data, 620 x 491, 8-bit/color RGBA, non-interlaced'
▲▲▲▲
Windowsで漢字ファイル名の入ったZIPファイルを解凍する。
そのまま解凍すると文字化けになる。convmvでも変換できない。そんな時、
$ sudo apt install unar
$ unar xxxx.zip
▲▲▲▲
サービスの一覧
sudo service --status-all
sudo systemctl list-units --type=service
▲▲▲▲
https://www.raspberrypi.org/forums/viewtopic.php?t=96273
Mouse cursor
より
・・・・・
白いカーソルにする。黒いのも。
sudo apt install dmz-cursor-theme
メインメニュー → ルックアンドフィールの設定をする(メインメニューエディターでチェックを入れる)→ マウスカーソル タグ → DMZ(白)で選択する
大きさの設定はメインメニュー → Appearance Settings → System → Mouse Cursor で大中小サイズ選択
▲▲▲▲
GREP でPerlの正規表現を使う。
指定文字列以外の行。
gerp -P '(?!1234)' test.txt
カッコ,?,!にはエスケープシーケンスはいらない。
▲▲▲▲
nanoエディタ行番号表示
~/.nanorc
ーーー
set linenumbers
追加。
▲▲▲▲
WiFi POWER ON/OFF
https://raspberrypi.stackexchange.com/questions/73727/turning-off-wifi-bluetooth-module
Turning off Wifi/ Bluetooth module
より
ON :
rfkill unblock wifi
OFF:
rfkill block wifi
▲▲▲▲
sshfs でシンボリックリンクを扱う
sshfs pi@192.168.xx.xxx:/home/xxx mnt -o follow_symlinks
2023-05-23 「USBシリアルケーブルでシリアルコンソール追加」
本体のUART PINはそのまま使って、シリアルコンソールを使いたい場合はUSBシリアルケーブルを差し込んでそれを
シリアルコンソールとして使う。デバイス名が変化する場合はUDEVルールでデバイス名をシンボリックリンクで設定する。
$ sudo mkdir -p /etc/systemd/system/getty@ttyUSB0.service.d
$ sudo nano /etc/systemd/system/getty@ttyUSB0.service.d/autologin.conf
---
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin pi --noclear %I 115200,38400,9600 vt220
---
自動ログインを希望しない場合は、"--autologin pi" を削除。
$ sudo ln -s /lib/systemd/system/getty@.service /etc/systemd/system/getty.target.wants/getty@ttyUSB0.service
$ sudo reboot
...
参考:https://gist.github.com/yoggy/de9a4a6405834f52accc
yoggy/電源を入れたときにtty1を自動ログインする設定あれこれ集.md
https://archlinuxarm.org/forum/viewtopic.php?f=31&t=5640
Serial Console Configuration Question
2023-05-23 「Micropython TELNET サーバー」
2.4Ghz Wifi TELNET Server
Raspberry piのLAN経由で接続ができなくなったときとか、ただのWIFIリモートUARTケーブルとして使う。
Pico-wとESP32のMicropythonで動作。
Pico-W,ESP32のmain.pyと同じところにファイル"wifi.conf"は書き込む。
++配線++
raspberry pi PIco-W
5V ----------------▶|--------VSYS
ダイオード
GND ---------------------------GND
GPIO 14(txd) ------------------GP1(RX)
GPIO 15(rxd)-------------------GP0(TX)
GP10 -----/\/\/\---▶|-----+
1K LED |
GND ------------------------+
TELNET接続時 UARTスピードにより
点滅時間が違う。
2秒以上点灯がある場合はLAN接続エラー。
ESP32
LED = IO 5
TXD = IO 17
RXD = IO 16
++設定++
Raspberry pi
シリアルコンソール有効
または、
Raspberry pi
USBシリアルケーブルをシリアルコンソール設定する。
このときは TXD ーーーー GP1
RXD ーーーー GP0
に接続する。
USBシリアルケーブルはPICO ProbeをコンパイルしてPICOに書き込んだものでもよい。
---wifi.conf---
ssid=xxxSSIDxxx
passwd=xxxPASSWORDxxx
network=192.168.12.xxx,255.255.255.0,192.168.12.1,192.168.1.1
port=23
led=5
-------
port省略時は、23。led省略時は10。
networkは、固定IP,ネットワークマスク、GATEWAY,DNSサーバアドレスの順。省略時は、DHCPによる。
---program----
# (c) K.Shimomura (The MIT License)
from machine import UART, Pin,Timer
import machine
import network, time
import socket
import select
import _thread
import re
import uos
# for micropython
baud = (115200, 57600, 38400, 19200, 9600, 0)
bidx = 0
btmr = 0
mname = uos.uname()[0]
'''
Timer Interrupt
'''
def RemoteGets(Timer):
global btmr, pa, bidx
# Run Wifi and Run UART speed by LED
btmr += 1
btmr &= 0xFF
if (btmr & (1<<(bidx+1))):
pa.value(1)
else:
pa.value(0)
'''
Telnet Protocol
'''
def will(id):
return b'\xff\xfb' + id
#print('will:',id)
def do(id):
return b'\xff\xfd' + id
#print('do:',id)
def wont(id):
return b'\xff\xfc' + id
#print('wont:',id)
def dont(id):
return b'\xff\xfe' + id
#print('dont:',id)
def negotiation(cl,polan):
tcmd = b''
subc = b'\x00'
while True:
res = polan.poll(300)
if not res:
c = None
break
c = cl.recv(1)
if c == b'\xFF': # IAC ?
c = cl.recv(1)
if c == b'\xfb': # WILL ?
tcmd += wont(cl.recv(1))
elif c == b'\xfd': # DO ?
tcmd += dont(cl.recv(1))
elif c == b'\xfc': # WON'T ?
tcmd += wont(cl.recv(1))
elif c == b'\xfe': # DON'T ?
tcmd += dont(cl.recv(1))
elif c == b'\xfa': # sub ?
subc = cl.recv(1)
continue
elif c == b'\xf0': # sub end ?
tcmd += wont(subc)
subc = b'\x00'
else:
if subc != b'\x00':
continue
else:
break
else:
if subc != b'\x00':
continue
else:
break
if len(tcmd) > 0:
cl.send(tcmd)
return c
'''
Password File 'wifi.conf'
ssid=xxxSSIDxxx
passwd=xxxPASSWORDxxx
network=192.168.12.xxx,255.255.255.0,192.168.12.1,192.168.1.1
port=23
led=5
'''
def Get_Wificonf():
ssid = ''
passwd = ''
content = ''
netw = [ '' ]
nport = 23
ledpin = 10
with open("wifi.conf", 'r') as file:
content = file.read()
if content != "":
configs = content.split("\n")
pattn = re.compile(r'=')
for c in configs:
if c == "":
continue
id = pattn.split(c)
if id[0].lower() == 'ssid':
ssid = id[1]
elif id[0].lower() == 'passwd':
passwd = id[1]
elif id[0].lower() == 'network':
netw = id[1].split(",")
if len(netw) < 4:
netw = [ "" ]
elif id[0].lower() == 'port':
try:
nport = int(id[1])
except:
pass
elif id[0].lower() == 'led':
try:
ledpin = int(id[1])
except:
pass
else:
pass
return (ssid, passwd, netw, nport, ledpin)
'''
Find null and write to serial console
'''
def CandSend(bstr, u0):
s = bstr.replace(b'\r\000', b'\r')
s = s.replace(b'\r\n',b'\r')
if s != b'\000':
u0.write(s)
'''
Telnet Server for micropython
Main
'''
network.country('JP')
if mname == 'rp2':
tim = Timer()
else:
tim = Timer(0)
if mname == 'rp2':
u0 = UART(0,baud[bidx],timeout=0)
else:
u0 = UART(2,baud[bidx],timeout=0, tx=17, rx=16)
while u0.any():
c = u0.read(1)
time.sleep_ms(5)
#print("UART baud:", baud[bidx])
u0_poll = select.poll()
'''
Initial Network and Connect WIFI
'''
wconf = Get_Wificonf()
wlssid = wconf[0]
wlpasswd = wconf[1]
wlnet = wconf[2]
wlport = wconf[3]
pa = Pin(wconf[4], Pin.OUT, value=0)
wlan = network.WLAN(network.STA_IF)
print('connecting to network...')
wlan.active(True)
# Set to Fixed IP address
if len(wlnet) == 4:
wlan.ifconfig((wlnet[0], wlnet[1], wlnet[2], wlnet[3]))
else:
pass
# Connect WIFI
wlan.connect(wlssid, wlpasswd)
max_wait = 10
while max_wait > 0:
if wlan.isconnected():
break
max_wait -= 1
print('waiting for connection...')
time.sleep(1)
if not wlan.isconnected():
pa.value(1)
if wlan.status() != 3:
time.sleep(2)
else:
time.sleep(5)
machine.soft_reset()
#raise RuntimeError('network connection failed')
else:
print('connected')
print(wlan.ifconfig())
# Waiting a client
addr = socket.getaddrinfo('0.0.0.0', wlport)[0][-1]
s = socket.socket()
poller = select.poll()
s.bind(addr)
s.listen(1)
print('listening on', addr)
while True:
'''
Connect Client
'''
cl, addr = s.accept()
poller.register(cl, select.POLLIN)
print('client connected from', addr)
# Start Interrupt Timer 10msec
# (Read Terminal Console to write client socket and LED ON)
tim.init(period=10, mode=Timer.PERIODIC, callback=RemoteGets)
u0.deinit()
#bidx = 0
if mname == 'rp2':
u0 = UART(0,baud[bidx],timeout=0)
else:
u0 = UART(2,baud[bidx],timeout=0, tx=17, rx=16)
while u0.any():
c = u0.read(1)
time.sleep_ms(5)
time.sleep_ms(100)
u0_poll.register(u0, select.POLLIN)
# Send protocol
cl.send(will(b'\x01')) # will
cl.send(do(b'\x22')) # do
while True:
res = poller.poll(0)
if not res:
continue
else:
r = negotiation(cl,poller)
if r != None:
CandSend(r, u0)
else:
pass
break
# Send Help Message
cl.send(b'Pico-w TELNET Server\r\n Change UART Baudrate with "~~".\r\n')
#
r0 = b'\00'
while True:
'''
Loop TELNET data Read
'''
try:
res = poller.poll(0)
if res:
r = cl.recv(128)
# Check Close socket (Disconnect Client)
if r == b'':
break
else:
pass
#
if r == b'~' and r0 == b'~':
# USRT baudrate change
u0_poll.unregister(u0)
u0.deinit()
bidx += 1
if baud[bidx] == 0:
bidx = 0
else:
pass
#print("UART baud:", baud[bidx])
if mname == 'rp2':
u0 = UART(0,baud[bidx],timeout=0)
else:
u0 = UART(2,baud[bidx],timeout=0, tx=17, rx=16)
# Read Noise data
while u0.any():
c = u0.read(1)
time.sleep_ms(5)
u0_poll.register(u0, select.POLLIN)
# Confirm To baudrate
# Check Printabled character
#u0.write(b'\r')
r0 = b' '
continue
else:
if r0 == b'~':
u0.write(r0)
else:
pass
if r0 != b'~' and r == b'~':
r0 = r
continue
else:
pass
r0 = r
# Check Enter key code
CandSend(r, u0)
else:
pass
except:
print("except")
try:
rtn = u0_poll.poll(0)
if rtn:
r = u0.read(128)
cl.send(r)
else:
pass
except:
print("int-except")
# Close Connect Client
# Close Timer Interrupt
tim.deinit()
time.sleep(0.2)
poller.unregister(cl)
# Connect LED OFF
pa.value(0)
cl.close()
2023-04-08 「Rasperry pi PICO-W」
Raspberry pi PICO Wが発売になったのでひとつ買ってみた。
デバッグプローブも欲しかったのでセットになったものを入手。
環境は
===== BOARD ( Memory 4MB ) ====
Raspberry Pi 400 Rev 1.0
======= OS ( 64 Bits ) ========
Debian GNU/Linux 11 (bullseye) 2023-2-21 bullseye Desktopイメージです。
===============================
または、
===== BOARD ( Memory 8MB ) ====
Raspberry Pi 4 Model B Rev 1.5
======= OS ( 64 Bits ) ========
Debian GNU/Linux 11 (bullseye)
===============================
NTPサーバより時刻データを取り込み表示する。
micropythonプログラム。
ssd1306モジュールはThonnyを使い取り込み、以下のプログラムはPICO-W基板へ"main.py"でセーブする。
----
# NTP Clock
from machine import Pin, I2C, RTC
import ssd1306 # 表示ライブラリ Thonnyで追加
import time
import network
import socket
import struct
import _thread
NTP_DELTA = 2208988800
host = "pool.ntp.org"
ssid = 'xxYour SSIDxx'
password = 'xxYour PASSWORDxx'
srtc = 0
rp2.country('JP')
def set_time(rtc):
NTP_QUERY = bytearray(48)
NTP_QUERY[0] = 0x23 # NTP V.4 , client, 設定時刻なし(RFC5905)
addr = socket.getaddrinfo(host, 123)[0][-1]
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
#s.settimeout(1)
res = s.sendto(NTP_QUERY, addr)
msg = s.recv(48)
val = struct.unpack("!I", msg[40:44])[0]
t = val - NTP_DELTA + 9 * 3600 # JST
tm = time.gmtime(t)
#print(tm)
rtc.datetime((tm[0], tm[1], tm[2], tm[6] + 1, tm[3], tm[4], tm[5], 0))
finally:
s.close()
def ntptime(rtc):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('connection...')
time.sleep(1)
if wlan.status() != 3:
print("Network connection Failed!")
else:
print('connected')
status = wlan.ifconfig()
print( 'ip = ' + status[0] )
set_time(rtc)
wlan.deinit()
def Clock():
rtc = RTC()
# I2C設定
i2c = I2C(0, sda=Pin(8), scl=Pin(9) )
addr = i2c.scan()
print( "I2C Address :" + hex(addr[0]) )
# 表示設定
display = ssd1306.SSD1306_I2C(128, 64, i2c)
display.poweron()
while True:
timd = rtc.datetime()
tsr ="%4d-%02d-%02d %d %02d:%02d:%02d %d" % timd
display.fill(0)
display.text("Time",48,10)
display.text(tsr[:10], 24, 30)
display.text(tsr[13:21],32, 40)
display.show()
time.sleep(1)
rtc = RTC()
ntptime(rtc)
print("%4d-%02d-%02d [%d] %02d:%02d:%02d %d" % rtc.datetime())
_thread.start_new_thread(Clock, ())
while True:
timd = rtc.datetime()
if srtc != timd[2] and timd[3] == 0:
ntptime(rtc)
srtc = timd[2]
else:
time.sleep(3600)
-----
□□□□□□□□□□
Debug Probe なしで使う
USB port ==================================================> PICO-W USB port
デバッグプローブUSBはまだUSBポートに差し込まない。
PICO-WのUSBケーブルをボードのSWを押しながら差し込む。
表示されたマスストレージデバイスに
~/pico//micropython/ports/rp2/build-PICO/firmware.uf2 ファイルをドラッグコピーする。
ファイル名が消えたら書き込まれたことになる。
配線を以下のようにする。
+------------------+
USB port ===| Debug Probe (U)-+---------------オレンジ----> PICO-W GPIO-1(RX UART) pin2
| (D) | D 未接続 イエロー----> PICO-W GPIO-0(TX UART) pin1
+------------------+ ブラック----> PICO-W GND pin3
USB port ==================================================> PICO-W USB port
$ sudo apt install minicom
PICO-W側のUSBケーブルを接続。
$ minicom -o -D /dev/ttyACM0
改行入力
>>> from machine import UART, Pin
>>> uart0 = UART(0,baudrate=115200, tx=Pin(0), rx=Pin(1))
>>> tsData= b'Hello world!!\r\n'
デバッグプローブのUSBケーブルを接続。
別端末ウィンドウより、
$ minicom -o -D /dev/ttyACM1
次にプログラム入力中ウィドウに以下を入力する。
>>> uart0.write(tsData)
デバッグプローブ側のウィンドウに"Hello world!!"が表示される。
>>> help('modules')
__main__ lwip uasyncio/lock ure
_boot math uasyncio/stream urequests
_boot_fat micropython ubinascii uselect
_onewire mip/__init__ ucollections usocket
_rp2 neopixel ucryptolib ussl
_thread network uctypes ustruct
_uasyncio ntptime uerrno usys
_webrepl onewire uhashlib utime
builtins rp2 uheapq uwebsocket
cmath uarray uio uzlib
dht uasyncio/__init__ ujson webrepl
ds18x20 uasyncio/core umachine webrepl_setup
framebuf uasyncio/event uos
gc uasyncio/funcs urandom
Plus any modules on the filesystem
>>> print(rp2.country())
XX
>>> rp2.country('JP')
>>> print(rp2.country())
JP
□□□□□□□□□□
Debug Probe を使う
getting_started_with_pico.pdf page-62
$ cd ~/pico
$ sudo apt install automake autoconf build-essential texinfo libtool libftdi-dev libusb-1.0-0-dev
$ git clone https://github.com/raspberrypi/openocd.git --branch rp2040 --depth=1
$ cd openocd
$ ./bootstrap
$ ./configure
$ make -j4
$ sudo make install
configureに引数はDebug Probeのときはない。
USB picoprobeのパーミッションの変更
sudo nano /etc/udev/rules.d/98-p-probe.rules
---
ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000c", MODE="0666"
---作成
sudo reboot
USBベンダーとプロダクトはlsusbコマンドで表示されるもの。
"ID 2e8a:000c Raspberry Pi Debug Probe (CMSIS-DAP)"
作成したら、リブートして有効にすること。
有効にしないとコンパイルはできるがデバッグができない。
$ cd ~/pico/pico-examples/blink
$ nano blink.c
-----
const uint LED_PIN = 15;
-----修正
$ cd ~/pico/pico-examples/build/blink
$ make -j4
配線を以下のようにする。
LEDに抵抗1KΩを直列に配線する。
GPIO-15(20) -\/\/\---▶|---- GND(18)
1K
+------------------+
USB port ===| Debug Probe (U)-+---------------オレンジ----> PICO-W GPIO-1(RX UART) pin2
| | イエロー----> PICO-W GPIO-0(TX UART) pin1
| | ブラック----> PICO-W GND pin3
| |
| (D)-+---------------オレンジ----> PICO-W SWCLK
+------------------+ ブラック----> PICO-W GND
イエロー----> PICO-W SWDIO
USB port ==================================================> PICO-W USB port
$ openocd -f interface/cmsis-dap.cfg -c "adapter speed 5000" -f target/rp2040.cfg -c "program blink.elf verify reset exit"
Debug Probeが刺さっていないとMSIS-DAPがないとエラーになる。
プログラムの書き込み。LEDが点滅する。
■GDBでデバッグ
Firewallが設定してある場合は、IPV6許可をする。
$ sudo apt install gdb-multiarch
最初のインストールで一緒に入るのかも。
$ cd ~/pico/pico-examples
$ cd build
$ export PICO_SDK_PATH=../../pico-sdk
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
$ cd hello_world/serial
$ make -j4
配線を上記のまま使う。
$ openocd -f interface/cmsis-dap.cfg -c "adapter speed 5000" -f target/rp2040.cfg
デバッグプローブ接続を先に接続して、別ウィンドウ1で
$ minicom -o -D /dev/ttyACM0
別ウィンドウ2で、
$ cd ~/pico/pico-examples/build/hello_world/serial
$ gdb-multiarch hello_serial.elf
(gdb) target remote localhost:3333
これを省略するには、
~/.gdbinit ファイルに
----
target remote localhost:3333
----
とする。
(gdb) load
(gdb) monitor reset init
(gdb) b main
(gdb) continue
main()で止まる
(gdb) continue
別ウィンドウ1で "Hello, world!" が表示される。
□□□□□□□□□□
自分のプロジェクト・WIFIアクセスポイント作成
$ cd ~/pico
$ git clone https://github.com/raspberrypi/pico-project-generator.git --branch master
$ cd pico-project-generator
$ ./pico_project.py --gui
Project Name: picow_access_point
ソース名になる
Location: 適当な場所
Board Type: pico_W
Pico Wireless OPtion: BAckground lwIP または、 Polled IwIP
Build Option: Run Build after generation
IDE OPtuin: SWD
[OK] クリック。雛形で生成コンパイルさせる。
その後、
~/pico/pico-examples/pico_w/wifi/access_point/ のディレクトリ dhcpserver、dnsserver と picow_access_point.cを
プロジェクトのディレクトリに上書きする。
├── CMakeLists.txt
├── build
├── dhcpserver
├── dnsserver
├── lwipopts.h
├── pico_sdk_import.cmake
└── picow_access_point.c
プログラム修正
$ nano picow_access_point.c
---
int main() {
stdio_init_all();
TCP_SERVER_T *state = calloc(1, sizeof(TCP_SERVER_T));
if (!state) {
DEBUG_printf("failed to allocate state\n");
return 1;
}
//if (cyw43_arch_init()) {
if (cyw43_arch_init_with_country(CYW43_COUNTRY_JAPAN)) { <<==修正 国コードJP 設定
DEBUG_printf("failed to initialise\n");
return 1;
}
uint32_t c_code = cyw43_arch_get_country_code(); <<==追加 国別コード
printf("contry-code:%c%c\n", c_code&0xFF,c_code>>8); <<==追加
const char *ap_name = "bxxxxx"; <<==SSID修正
#if 1
const char *password = "5xxxxx"; <<==パスワード修正
#else
const char *password = NULL;
#endif
cyw43_arch_enable_ap_mode(ap_name, password, CYW43_AUTH_WPA2_AES_PSK);
--- 追加,修正する
$ nano CMakeLists.txt
---
add_executable(picow_access_point picow_access_point.c
dhcpserver/dhcpserver.c # カッコ内に2業追加
dnsserver/dnsserver.c #
)
;;
;;
target_include_directories(picow_access_point PRIVATE
${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts or any other standard includes, if required
${CMAKE_CURRENT_LIST_DIR}/dhcpserver # 2行追加
${CMAKE_CURRENT_LIST_DIR}/dnsserver #
)
---
プロジェクトのbuildデイレクトリで
$ make
エラーがなければ、
$ openocd -f interface/cmsis-dap.cfg -c "adapter speed 5000" -f target/rp2040.cfg -c "program picow_access_point.elf verify reset exit"
書き込み。
$ minicom -o -D /dev/ttyACM0
PICO-Wをリセットし、プログラムに設定したWIFI SSIDに接続して、ブラウザで、
http://192.168.4.1
URLでWEBページが表示される。LED ON/OFFをクリックするとUSBコネクタ脇の緑LEDが点滅する。
参照ドキュメント
PicoW-A4-Pinout.pdf
debug-connector-specification.pdf
getting-started-with-pico.pdf
pico-w-datasheet.pdf
raspberry-pi-pico-c-sdk.pdf
raspberry-pi-pico-python-sdk.pdf
connecting-to-the-internet-with-pico-w.pdf
https://www.raspberrypi.com/documentation/microcontrollers/debug-probe.html
Raspberry Pi Debug Probe - About the Debug Probe
2023-12-01 「オートフォーカスカメラIMX519 INSTALL」
Piカメラ Arducam 16MP IMX519搭載 オート フォーカス [B0371]
==== bookworm =======arm64=======
Quick Start
https://docs.arducam.com/Raspberry-Pi-Camera/Native-camera/Quick-Start-Guide/
libcamera and libcamera-apps
https://docs.arducam.com/Raspberry-Pi-Camera/Native-camera/Libcamera-User-Guide/#autofocusmanual-focus-function
...
Quick Start / SOFTWARE GUIDE for IMX519 Autofocus Camera
wget -O install_pivariety_pkgs.sh https://github.com/ArduCAM/Arducam-Pivariety-V4L2-Driver/releases/download/install_script/install_pivariety_pkgs.sh
chmod +x install_pivariety_pkgs.sh
./install_pivariety_pkgs.sh -p libcamera
./install_pivariety_pkgs.sh -p libcamera_apps
sudo nano /boot/config.txt
...
dtoverlay=imx519
...追加
sudo reboot
libcamera-jpeg -o test.jpg
libcamera-still -t 5000
libcamera-still -t 5000 -n -o test.jpg
libcamera-still -t 0 --autofocus-mode auto
libcamera-vid -t 10000 -o test.h264
libcamera-still -t 5000 --datetime -n --timelapse 1000
libcamera-vid -t 50000 --autofocus-mode continuous --framerate 1 --autofocus-speed fast -n -o test.h264
2023-11-09 「google翻訳」
●Google翻訳,スピーチ
$ sudo apt install python3-venv
$ sudo apt install sox libsox-fmt-all
$ python3 -m venv venv
$ source venv/bin/activate
(venv) pi@xxxxx:~ $ pip3 install googletrans==4.0.0-rc1
(venv) pi@xxxxx:~ $ nano tr.py
---
from googletrans import Translator
tr = Translator()
txt = "I'm here."
ja1 = tr.translate(txt, src="en", dest="ja")
print("翻訳結果:",end='')
print(txt,end='')
print(" ==> ",end='')
print(ja1.text)
---
(venv) pi@xxxxx:~ $ python tr.py
翻訳結果:I'm here. ==> 私はここにいます。
(venv) pi@xxxxx:~ $ pip3 install google-speech
(venv) pi@xxxxx:~ $ google_speech -h
sox EFFECTを追加する。(-e の位置注意)
(venv) pi@xxxxx:~ $ google_speech -e speed 0.8 -l en "Hello"
ファイルへ。
(venv) pi@xxxxx:~ $ google_speech -l en -o out1.mp3 "Hello"; sox out1.mp3 out2.mp3 speed 0.8
●DOCKERコンテナ
1.Dockerfile
---
# translate/Dockerfile
FROM arm64v8/debian
MAINTAINER “K.Shimoura"
ENV container docker
ENV DEBIAN_FRONTEND noninteractive
# SIGNAL=37
STOPSIGNAL SIGRTMIN+3
# root パスワード設定
RUN printf "rootdocker\nrootdocker\n"| passwd > /dev/null 2>&1
RUN apt update
# ロケール設定
RUN apt install -y locales locales-all
ENV LC_ALL ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP.UTF-8
ENV TZ Asia/Tokyo
RUN echo 'export LC_ALL="ja_JP.UTF-8"' >> /etc/profile
RUN echo 'export LANG="ja_JP.UTF-8"' >> /etc/profile
RUN echo 'export LANGUAGE="ja_JP:jp"' >> /etc/profile
RUN echo 'export TZ="Asia/Tokyo"' >> /etc/profile
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 1 ユーザ登録
# ユーザ作成
RUN echo "pi:pidocker:1000:1000:,,,:/home/pi:/bin/bash"|newusers
# ユーザ 設定
RUN cp -r /etc/skel/.[a-z]* /home/pi
RUN chown -R pi:pi /home/pi
RUN adduser pi audio
# アプリケーションインストール
RUN apt install -y alsa-utils
RUN apt install -y nano python3 python3-pip git
RUN apt install -y python-is-python3
RUN apt install -y python3-venv
RUN apt install -y sox libsox-fmt-all
RUN su - pi -c "python3 -m venv /home/pi/venv"
RUN su - pi -c "/bin/bash -c 'source /home/pi/venv/bin/activate;pip3 install googletrans==4.0.0-rc1'"
RUN su - pi -c "/bin/bash -c 'source /home/pi/venv/bin/activate;pip3 install google-speech'"
RUN apt install -y sudo
RUN printf 'pi ALL=(ALL) NOPASSWD: ALL\n' > /etc/sudoers.d/010_pi-nopasswd
RUN echo "if [ -n \$VIRTUAL_ENV_PROMPT ]; then PS1=\"\$VIRTUAL_ENV_PROMPT\$PS1\";fi"| tee -a /home/pi/.bashrc
# ユーザpiで実行
WORKDIR /home/pi
COPY config.sh /home/pi
RUN chmod +x /home/pi/config.sh
RUN chown pi:pi /home/pi/config.sh
USER pi
CMD ["/home/pi/config.sh"]
#CMD ["/home/pi/config.sh", "USB Sound Device" ]
# コンテナ内でaplay -l での一覧でMP3,声を再生するデバイス名を引数で与える
# 声を再生しないときはデバイス名を省略する
---
2.環境設定
$ nano config.sh
---
#!/bin/bash
# P1: sound device
if [ "$1" != "" ]; then
sa=`aplay -l | grep "$1"| sed -e "s/^[^0-9]\+\([0-9]\+\).*$/\1/"`
printf "defaults.pcm.card ${sa}\ndefaults.ctl.card ${sa}\n" | sudo tee /etc/asound.conf
fi
source /home/pi/venv/bin/activate;/bin/bash
---作成
3.コンテナ作成
$ docker build -t arm64/translate .
4.コンテナ実行
$ docker run -ti --rm -v ~/mp3:/home/pi/mp3 --name translate arm64/translate
音を出す場合は、--privileged を指定する。mp3ファイル作成はいらない。
5.コマンド実行
(venv) pi@xxxxxxxx:~$ nano tr.py
---
from googletrans import Translator
tr = Translator()
txt = "I'm here."
ja1 = tr.translate(txt, src="en", dest="ja")
print("翻訳結果:",end='')
print(txt,end='')
print(" ==> ",end='')
print(ja1.text)
---
(venv) pi@xxxxxxxx:~$ python tr.py
翻訳結果:I'm here. ==> 私はここにいます。
(venv) pi@xxxxxxxx:~$ google_speech -h
(venv) pi@xxxxxxxx:~$ google_speech -l en -o mp3/out1.mp3 "Hi, How are you?"
(venv) pi@xxxxxxxx:~$ sox mp3/out1.mp3 mp3/out2.mp3 speed 0.8
5.コンテナ終了
(venv) pi@xxxxxxxx:~$ exit
2023-03-07 「jupyter notebook, scikit-learn インストール」
■東京大学のデータサイエンティスト育成講座
塚本邦尊、 山田典一、 大澤文孝 著 マイナビ出版 2019(1),2022(17)
サンプルデータをダウンロードしてやってみた。
サンプルデータはまだ修正されていなので本のプログラムのように修正する。
☆Chapter2-3-2-2 固有値と固有ベクトル
# 固有値と固有ベクトル
eig_value, eig_vector = linalg.eig(matrix)
# 固有値と固有ベクトル
print('固有値')
print(eig_value)
print('固有ベクトル')
print(eig_vector)
------
固有値
[-1.+0.j 2.+0.j 2.+0.j]
固有ベクトル
[[-0.577 -0.578 0.579]
[-0.577 -0.21 -0.788]
[-0.577 0.788 0.209]]
----
numpy.linag.eig()でも同じ
Windowsマシンでもやってみたが本に記載されたような数値にはならない。
----
import numpy as np
import scipy as sc
a = np.array([[1,-1,-1],[-1,1,-1],[-1,-1,1]])
sc.linalg.eig(a)
(array([-1.+0.j, 2.+0.j, 2.+0.j]),
array([[ 0.57735027, 0.81649658, 0.40824829],
[ 0.57735027, -0.40824829, -0.81649658],
[ 0.57735027, -0.40824829, 0.40824829]]))
---
WEB上の他の配列データを見てやってみたが、示されている数値になるものはある。
本の配列データは誤差が大きくなるものなんだろうか?
データサイエンスをやって見るにはいいきっかけなのかもしれない。
☆Chapter4-4-3-1 で3Dグラフが書けないのが気になって調べてみた。
”<Figure size 600x400 with 0 Axes>”これは3Dグラフから出るメッセージなんだ。
グラフは出ない。
参考: https://matplotlib.org/2.0.2/mpl_toolkits/mplot3d/tutorial.html
mplot3d tutorial より
そこでplot_wireframe()例にあるように修正する。
----
fig = plt.figure(dpi=100)
# ax = Axes3D(fig)
ax = fig.add_subplot(111, projection='3d') # <<<===
ax.plot_wireframe(x, y, z)
# x,y,zラベルの設定など
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('f(x, y)')
----
その他に、
---
%matplotlib notebook
---
とするとマウスでグルグル回せることがわかった。
もうひとつ、この本はanaconda環境でやると便利といっていますが、Raspberry piでは今のところインストール環境が
ない。minicondaがあるというので検索してみた。
元ネタ:https://stackoverflow.com/questions/71150891/raspberry-pi-3-miniconda-install-aarch64-error
Raspberry Pi 3 Miniconda install aarch64 error
この手順でやってみた。
ーー
$ wget https://github.com/conda-forge/miniforge/releases/download/22.11.1-4/Mambaforge-22.11.1-4-Linux-aarch64.sh
$ bash Mambaforge-22.11.1-4-Linux-aarch64.sh
ライセンス表示、インストールするかの質問がくる。
インストールが終わると、「Do you wish the installer to initialize Mambaforge by running conda init?」
と聞かれてyesとすると.bashrcに自動的に端末ターミナルを開くとconda initが実行されるスクリプトが追加される。
NOとする。
$ nano ~/.bashrc
---
export PATH="/home/ユーザ名/mambaforge/bin:$PATH"
---を最後に追加する。
$ source ~/.bashrc
PATHが追加される。
$ conda init
$ conda list
インストールされているのが表示される。なにもない。conda環境だけである。
元ネタではsudoコマンドであるがsudoにすると/root/.bashrc , /rootに環境ができてしまう。
本には使うモジュールはまとまって記載されているので手でやってもいいかなと思う。
特にCONDA環境でなくてもできるので使わないことにした。
☆Chapter5-3-3-3 微分方程式の計算
3Dグラフが出ない。3Dの設定の関数呼び出しが誤りになっている。
mplot3d tutorialより、同様に修正する
---
# 関数の呼び出し
v = odeint(lorenz_func, v0, t, args=(p, r, b))
# 可視化
fig = plt.figure()
# ax = fig.gca(projection='3d')
ax = fig.add_subplot(111,projection='3d') # <<<=== 修正
ax.plot(v[:, 0], v[:, 1], v[:, 2])
# ラベルなど
plt.title('Lorenz')
plt.grid(True)
---
☆Chapter6 数値が半分くらいのがある。
他にもある。
『手を動かして学ぶデータ分析』なんです。
表示された数値があっていたり、末尾の数値が1,2桁違っていたとしたら正しいと思えるが、それ以外は
グラフのプロットする位置が違っていたり、数値が半分、倍の時っはなんとも言えない。
バカが開けてはいけない”データサイエンス”の扉かもしれない。
☆Chapter10でload_boston()が使われていた。エラーメッセージに表示される手順でやってみた。
---- Iload_boston.ipynb -------
# # ボストンデータをインターネットから読み込む
#
# load_boston() で出るエラーメッセージより作成
# In[1]:
import pandas as pd
import numpy as np
from sklearn.utils import Bunch
from io import StringIO
import requests
def Iload_boston():
data_url = "http://lib.stat.cmu.edu/datasets/boston"
try:
file_data = requests.get(data_url).text
# bostonテキスト行データ
except:
print("インターネットデータ退避できていません")
return None
idata = pd.read_csv(StringIO(file_data), sep="\s+", skiprows=22, header=None)
# 先頭22行読み飛ばし BOSTONデータ数値抽出
vdata = np.hstack([idata.values[::2, :], idata.values[1::2, :2]])
# 現行 1カラム目から、11データ 次の行に 1カラム目から、2データ = BOSTON数値データ
target = idata.values[1::2, 2]
# 次の行の 3カラム目をtaget データ
raw_feature_names = pd.read_csv(StringIO(file_data), sep="\s+", skiprows=7,nrows=13,usecols=[0], header=None)
# ファイル 8行目から、13行分が boston データ表のタイトル
feature_names = raw_feature_names[0].to_list()
# タイトルの行型データから、リスト型に変換
return Bunch(data=vdata,target=target,feature_names=feature_names)
# In[2]:
qdata = Iload_boston()
# DataFrameにデータを格納
X = pd.DataFrame(qdata.data, columns=qdata.feature_names)
# 住宅価格の中央値(MEDV)のデータを用意
y = pd.Series(qdata.target, name='MEDV')
# Xとyを結合して先頭の5行を表示
X.join(y).head()
-----
■jupyter-notebook インストール
$ sudo apt install -y jupyter-notebook
$ jupyter notebook --generate-config
jupyter notebook 環境設定 パスワード設定
$ jupyter notebook password
実行は、プログラム格納ディレクトリで
$ jupyter notebook
(X winowのデスクトップOSでlocalhost接続でブラウザが起動する)
$ jupyter notebook --ip=* --no-browser
(別PCのブラウザで使う)
python言語以外でも使おうと思えば、”!シェルスクリプト”で stdoutの結果が残せるのでいいかも。
■英文構文解析
参考:https://qiita.com/krang/items/6e34c595ac77e46c3650
pythonのnltkライブラリを使ってstanford parserを導入する
java インストールを追加した。
RUN apt install -y openjdk-17-jdk
docker run {scikit-learnデモ解凍ディレクトリ} に、
https://stanfordnlp.github.io/CoreNLP/
Stanford CoreNLP – Natural language software
[Download CoreNLP 4.5.2] ボタンクリックしてダウンロードしたものを解凍する。
その後、コンテナを起動する。
----- jupyter notebook -----
# In[1]:
from nltk.parse.stanford import *
# stanford corenlp ダウンロードしたディレクトリ(Docker内から見えるのもの)
JAR_FILE = "/home/pi/EXT/stanford-corenlp-4.5.2/stanford-corenlp-4.5.2.jar"
MODEL_FILE = "/home/pi/EXT/stanford-corenlp-4.5.2/stanford-corenlp-4.5.2-models.jar"
sentence = 'The brown fox is quick and he is jumping over the lazy dog.'
parser = StanfordParser(JAR_FILE,MODEL_FILE)
out = parser.raw_parse(sentence)
trees = list(out)
# In[2]:
from IPython.display import display, SVG, HTML
from nltk.tree import Tree, TreePrettyPrinter
print("英文解析のやり方=",len(trees))
tree = trees[0]
ctree = str(tree)
print("\n --- キャラクタグラフィック ---")
tree.pretty_print()
print("\n --- SVGグラフィック ---")
display(SVG(TreePrettyPrinter(Tree.fromstring(ctree)).svg()))
---- jupyter end ------------
====================================================
JAVAで起動する stanfordnlpは、使い方に2種類の方法がある。
上記のように解釈するたびに起動する方法とサーバーとして動作させる
方法がある
SVGの作成は、
①TreePrettyPrinter(Tree.fromstring(ctree)).svg()
②img = svgling.draw_tree(trees[0])
svg_data = img.get_svg()
パーサデータで木構造SVGを作るには, nltk, svglingで作成する2種類ある
====================================================
音声で確認する。
java インストールを追加した。
..
# sound インストール
RUN apt install -y alsa-utils
RUN printf 'defaults.pcm.card 2\ndefaults.ctl.card 2\n' > /etc/asound.conf
RUN apt install -y sox libsox-fmt-all
;;
RUN pip3 install googletrans==4.0.0-rc1
RUN pip3 install google_speech
RUN echo 'rootdocker'| su - root -c "adduser pi audio"
..
docker run に 、--privileged を指定する
-----jupyter notebook -----
# In[1]:
from googletrans import Translator
txt = input("英文を入力してください :")
''' 英語・日本語 翻訳'''
tr = Translator()
ja1 = tr.translate(txt, src="en", dest="ja")
print("\n翻訳結果:",end='')
print(txt,end='')
print(" ==> ",end='')
print(ja1.text)
# In[2]:
from google_speech import Speech
from IPython.display import display, HTML
''' 英文を読み上げます MP3ファイルで録音します '''
speech = Speech(txt, "en")
speech.play()
filn = "speech.mp3"
speech.save(filn)
# In[3]:
display(HTML("<audio controls src=\"speech.mp3\" type=\"audio/mp3\">英語発音</audio></br>"))
-----jupyter end -----
■scikit-learn インストール
scikit-learn WEB ページに従って。
https://scikit-learn.org ==>> Getting Started ==>> installation instructions ==>>
[Third party distributions of scikit-learn] . [Debian/Ubuntu]
$ sudo apt install -y python3-sklearn python3-sklearn-lib
https://stackoverflow.com/questions/35064304/runtimeerror-make-sure-the-graphviz-executables-are-on-your-systems-path-aft
「RuntimeError: Make sure the Graphviz executables are on your system's path" after installing Graphviz 2.38」
より
$ sudo apt install -y graphviz
scikit-learnデモで使うものの追加
$ pip3 install graphviz
$ pip3 install pooch
$ pip3 install plotly
$ pip3 install annoy
$ pip3 install nmslib
$ pip3 install pooch
$ pip3 install mlxtend
$ sudo apt install python3-skimage
グラフのタイトルに日本語を使う場合に、
$ pip3 install japanize-matplotlib
サンプルデモのページにあるように、examplesを始める前に必ずやること。
$ pip3 install --upgrade scikit-learn
▶ sci kit learn 1.2.1 Examples
https://scikit-learn.org/stable/auto_examples/index.html
下にあるデータをダウンロードする。
適当なディレクトリに解凍する。
●●●●● DOCKERインストール ●●●●●
Dockerコンテナにインストールする
1. Dockerfile
---
# arm64/bullseye-skl/Dockerfile
FROM arm64v8/debian
MAINTAINER “K.Shimoura"
ENV container docker
ENV DEBIAN_FRONTEND noninteractive
# SIGNAL=37
STOPSIGNAL SIGRTMIN+3
# root パスワード設定
RUN printf "rootdocker\nrootdocker\n"| passwd > /dev/null 2>&1
RUN apt update
# ロケール設定
RUN apt install -y locales locales-all
ENV LC_ALL ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP.UTF-8
ENV TZ Asia/Tokyo
RUN echo 'export LC_ALL="ja_JP.UTF-8"' >> /etc/profile
RUN echo 'export LANG="ja_JP.UTF-8"' >> /etc/profile
RUN echo 'export LANGUAGE="ja_JP:jp"' >> /etc/profile
RUN echo 'export TZ="Asia/Tokyo"' >> /etc/profile
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 1 ユーザ登録
# ユーザ作成
RUN echo "pi:pidocker:1000:1000:,,,:/home/pi:/bin/bash"|newusers
# ユーザ 設定
RUN cp -r /etc/skel/.[a-z]* /home/pi
RUN chown -R pi:pi /home/pi
# アプリケーションインストール
RUN apt install -y nano python3 python3-pip git
# jupyter-notebook インストール
RUN apt install -y jupyter-notebook
# scikit-learn インストール
RUN apt install -y python3-sklearn python3-sklearn-lib graphviz
RUN apt install -y python3-skimage
# java インストール
RUN apt install -y openjdk-17-jdk
# sound インストール
RUN apt install -y alsa-utils
RUN printf 'defaults.pcm.card 2\ndefaults.ctl.card 2\n' > /etc/asound.conf
RUN apt install -y sox libsox-fmt-all
# ユーザpiで実行
WORKDIR /home/pi
USER pi
# jupyter notebook 環境設定
RUN jupyter notebook --generate-config
RUN sed -i -e "s/# c.NotebookApp.open_browser.*$/c.NotebookApp.open_browser = False/" /home/pi/.jupyter/jupyter_notebook_config.py
RUN sed -i -e "s/# c.NotebookApp.ip.*$/c.NotebookApp.ip = '*'/" /home/pi/.jupyter/jupyter_notebook_config.py
# jupyter notebook 環境設定 パスワード設定
#RUN pss=`shuf -i 1-239 -n 1`; echo "jupyter$pss" > /home/pi/.jupyter/pss.txt; \
# echo "jupyter$pss"|python3 -c 'from notebook.auth import passwd;print("{\n \"NotebookApp\": {\n \"password\": \"",end=""); print(passwd(input()),end=""); print("\"\n }\n}")' > /home/pi/.jupyter/jupyter_notebook_config.json; \
# echo "";echo "jupyter notebookパスワード: jupyter$pss"; echo ""
RUN pss='skldocker'; echo "$pss" > /home/pi/.jupyter/pss.txt; \
echo "$pss"|python3 -c 'from notebook.auth import passwd;print("{\n \"NotebookApp\": {\n \"password\": \"",end=""); print(passwd(input()),end=""); print("\"\n }\n}")' > /home/pi/.jupyter/jupyter_notebook_config.json; \
echo "";echo "jupyter notebookパスワード: $pss"; echo ""
RUN chmod 600 /home/pi/.jupyter/jupyter_notebook_config.json
RUN chmod 400 /home/pi/.jupyter/pss.txt
# scikit-learn python module インストール
RUN pip3 install numpy scipy matplotlib ipython pandas pillow graphviz mglearn
RUN pip3 install pooch plotly annoy nmslib pooch nltk spacy
RUN pip3 install japanize-matplotlib
RUN python3 -m spacy download en
RUN pip3 install --upgrade scikit-learn
RUN pip3 install mlxtend
RUN python3 -c "import nltk;nltk.download('all')"
RUN pip3 install googletrans==4.0.0-rc1
RUN pip3 install google_speech
RUN echo 'rootdocker'| su - root -c "adduser pi audio"
---
jupyter-notebook パスワードは適当なものに修正すること。pss='skldocker' ==> pss='xxxx'。
パスワードの確認は、コンテナ実行中に、
docker ps
docker exec {docker psでのコンテナID} cat /home/pi/.jupyter/pss.txt
で表示できるように/home/pi/.jupter/pss.txtに書き込んでいる。
jupyter-notebook 動作環境のうちで、IPアドレスは特に制限なし、ローカルブラウザは起動しないに設定している。
(jupyter notebook --ip=* --no-browser と同じ)
nltkがインストールされるのでnltkデータを全ダウンロードする。
2. build
$ docker build -t arm64/bullseye-skl .
3. run
$ docker run -ti --rm -v {scikit-learnデモ解凍ディレクトリ}:/home/pi/EXT -p 8888:8888 arm64/bllseye-skl bash -c "cd EXT;jupyter notebook;bash"
bash -c の最後の bash はjupyter-notebookを終了してもコンテが実行終了しないように。
HTTPポートは、-p 8888:8888 の -p {他のポートとかさならないポート番号}:8888 に修正すること。
コンテナ実行前に
https://scikit-learn.org/stable/auto_examples/index.html WEBページ下にあるjupyter-notebook用のzipファイルを
{scikit-learnデモ解凍ディレクトリ}に解凍しておく。
4. scikit-learn,pythonを使うには他のPCのブラウザから
他のPCのブラウザで、
http://{IPアドレス}:8888
で使う。
使ったプログラムとデータは、コンテナ外の{scikit-learnデモ解凍ディレクトリ}に残る。
5. パッケージ、モジュールが足りない場合
docker ps
apt install する場合、
docker exec -ti -u root コンテナID bash
pip3 install する場合、
docker exec -ti コンテナID bash
カレントディレクトリが /home/pi/EXT になっているので注意する。
パッケージ、モジュールを追加した場合、その他のメモリを修正した場合はコンテナ終了でなくなるので
残したい場合は必ず docker commit すること。
commitする前にjupyter-notebookは終わらせておいたほうがいいかもしれない。
参照:https://qiita.com/alchemist/items/ce7f6790bdc2c7cee674
投稿日 2019年06月22日 更新日 2019年06月22日
2019年版 リモートサーバでJupyter Notebookを実行する方法
######## 以下は参考資料 ##########################
モジュールが日々アップデートされているのでインストールし直した時、思わぬところでエラーが出る場合がある。
pandas.plotでは、タイトルに日本語があると文字ばけする場合、
1) OSにインストールされているフォントファミリーを確認
$ fc-list -f "%{family}\n"
..
::
IPA Pゴシック,IPAPGothic
Takao Pゴシック,TakaoPGothic
IPA P明朝,IPAPMincho
IPAゴシック,IPAGothic
Takao P明朝,TakaoPMincho
Takao Pゴシック,TakaoPGothic
Takao明朝,TakaoMincho
Takao P明朝,TakaoPMincho
Takaoゴシック,TakaoGothic
::
..
2) 日本語フォントが見つからない場合
fonts-takaoか fonts-ipafontをインストールする。
3) matplotlibにフォントを選択する
---python code--
import matplotlib
#matplotlib.rc('font', family='TakaoPMincho')
matplotlib.rc('font', family='IPAGothic')
または
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'IPAGothic"
または、
import matplotlib.pyplot as plt
import japanize_matplotlib
4) それでも文字化け
$ ls ~/.cache/matplotlib
fontlist-v330.json 表示されたjsonファイル削除
$ rm ~/.cache/matplotlib/fontlist-v330.json
Jupyter notebook カーネル再起動
======================
▶ sci kit learn 1.2.0 Examples
https://scikit-learn.org/stable/auto_examples/index.html
下にあるデータをダウンロードする。
動かないのは2,3個なのでscikit learn元にあるのが一番かな。
$ sudo apt install python3-skimage
$ pip3 install pooch
$ pip3 install plotly
$ pip3 install annoy
$ pip3 install nmslib
$ pip3 install pooch
▶オライリー
「Pythonではじめる機械学習」
...
github からサンプルダウンロード
$ git clone https://github.com/amueller/introduction_to_ml_with_python.git
ダウンロードしたサンプルプログラムが実行できる。
そのままでは bostonデータ を使うことができない。
bostonデータ以外では、結果がずれているのがある。
①load_boston() でエラーとなる。load_boston() 自分用に作る。
load_boston()は上記のように。
def plot_learning_curve(est, X, y):
training_set_size, train_scores, test_scores = learning_curve(
est, X, y, train_sizes=np.linspace(.1, 1, 20), cv=KFold(20, shuffle=True, random_state=1))
estimator_name = est.__class__.__name__
line = plt.plot(training_set_size, train_scores.mean(axis=1), '--',
label="training " + estimator_name)
plt.plot(training_set_size, test_scores.mean(axis=1), '-',
label="test " + estimator_name, c=line[0].get_color())
plt.xlabel('Training set size')
plt.ylabel('Score (R^2)')
plt.ylim(0, 1.1)
def load_boston_extended():
boston = load_boston()
X = boston.data
X = MinMaxScaler().fit_transform(boston.data)
X = PolynomialFeatures(degree=2, include_bias=False).fit_transform(X)
return X, boston.target
def plot_ridge_n_samples():
X, y = load_boston_extended()
plot_learning_curve(Ridge(alpha=1), X, y)
plot_learning_curve(LinearRegression(), X, y)
plt.legend(loc=(0, 1.05), ncol=2, fontsize=11)
....
実行sklearnディレクトリに。
./load_boston.py
使う時、
---------source----
import load_boston
boston = load_boston.load_boston()
X, y = load_boston.load_boston_extended()
-------------------
あとは、import load_boston でエラーが出たらコメントにする。
②エラーになる。
$ nano preamble.py
---
from mglearn import plot_helpers <<==追加
import mglearn
from cycler import cycler
set_matplotlib_formats('pdf', 'png')
plt.rcParams['savefig.dpi'] = 300
plt.rcParams['image.cmap'] = "viridis"
plt.rcParams['image.interpolation'] = "none"
plt.rcParams['savefig.bbox'] = "tight"
plt.rcParams['lines.linewidth'] = 2
plt.rcParams['legend.numpoints'] = 1
plt.rc('axes', prop_cycle=(
cycler('color', plot_helpers.cm_cycle.colors) + <<==修正
cycler('linestyle', ['-', '-', "--", (0, (3, 3)), (0, (1.5, 1.5))])))
...修正
3章のサンプル実行で写真の色がでないのがあるのでこの修正では足りない。
③memoryでエラーになる。
$ nano ~/.local/lib/python3.9/site-packages/mglearn/plot_nmf.py
---
#memory = Memory(cachedir="cache")
memory = Memory("cachedir")
---修正
$ nano ~/.local/lib/python3.9/site-packages/mglearn/plot_pca.py
---
memory = Memory("cachedir")
--- 修正
④その他
$ nano ~/.local/lib/python3.9/site-packages/mglearn/datasets.py
---
#from sklearn.datasets import load_boston
;;
#from .make_blobs import make_blobs
from sklearn.datasets import make_blobs
::
def make_forge():
# a carefully hand-designed dataset lol
X, y = make_blobs(centers=2, random_state=4, n_samples=30)
y[np.array([7, 27])] = 0
mask = np.ones(len(X), dtype=bool) <<==np.bool修正
mask[np.array([0, 1, 5, 26])] = 0
X, y = X[mask], y[mask]
return X, y
---修正
同様に
$ nano ~/.local/lib/python3.9/site-packages/mglearn/tools.py
---
def make_handcrafted_dataset():
# a carefully hand-designed dataset lol
X, y = make_blobs(centers=2, random_state=4, n_samples=30)
y[np.array([7, 27])] = 0
mask = np.ones(len(X), dtype=bool) <<===
mask[np.array([0, 1, 5, 26])] = 0
X, y = X[mask], y[mask]
return X, y
---修正
$ nano ~/.local/lib/python3.9/site-packages/mlxtend/evaluate/holdout.py
---
def split(self, X, y, groups=None):
---も同様に修正する。
編集:03-unsupervised-learning.ipynb
IN[24] mask = np.zeros(people.target.shape, dtype=bool)
..
(★3Dグラフがかけない。)
(★顔写真が黒くなる。)
編集:04-unsupervised-learning.ipynb
IN[14] print(ohe.get_feature_names_out())
IN[35] print("Polynomial feature names:\n{}".format(poly.get_feature_names_out()))
IN[38] print("Polynomial feature names:\n{}".format(poly.get_feature_names_out()))
IN[71] features_poly = poly_transformer.get_feature_names_out(features)
..
★★:05-unsupervised-learning.ipynb
IN[24] mglearn.plots.plot_cross_val_selection()
でエラーになる。(??)
★★:06-unsupervised-learning.ipynb
OUT[27] 結果数値が一致しない。
編集:07-unsupervised-learning.ipynb
IN[16] feature_names = vect.get_feature_names_out()
IN[21] feature_names = vect.get_feature_names_out()
他の.get_feature_namesも、.get_feature_names_outに修正する。
..
★★:07-unsupervised-learning.ipynb
IN[35] pipe = make_pipeline(TfidfVectorizer(min_df=5), LogisticRegression())
::
:: の欄で中断する。
▶秀和システム
scikit-learn データ分析 実装ハンドブック
...
モジュールgoogle以外はない時pip3 installする。
load_bostonでエラーになるので、「PYTHONではじめる機械学習」で使ったファイルを、
実行ディレクトリに、data, descrを作成し、ファイルをコピー。
./data/boston_house_prices.csv
./descr/boston_house_prices.rst
./load_boston.py
使う時の直前で、
ーーーーーーーー
import os
import sys
import subprocess
s = subprocess.check_output("pwd")
sys.path.append(os.path.join(s.decode('utf-8').replace("\n", ""), '..'))
#print(s.decode('utf-8').replace("\n", ""))
import pprint
pprint.pprint(sys.path)
ーーーーーーーーーを実行する。
使うところで、
---------source----
import load_boston
boston = load_boston.load_boston()
にする。
section3_4_1.ipynb 確率的勾配降下法の回帰モデルを作成 でエラー。
section3_7_1.ipynb 決定木回帰のモデルを作成 でエラー。
section3_7_2.ipynb ランダムフォレスト回帰のモデルを作成 でエラー。
section4_4_1.ipynb 最初のグラフがでない。
訓練データのプロットの 前に %matplotlib inline、あとにplt.show()。
section4_4_2.ipynb
訓練データのプロットの 前に %matplotlib inline、あとにplt.show()。
section4_5_1.ipynb google.colab がないのでエラー。
8章はプログラムがない。
▶seaborn 徹底入門!Pythonを使って手軽で綺麗なデータ可視化8連発
https://www.codexa.net/seaborn-python/
(きれいなグラフが書ける)
$pip3 install seaborn
--
#sns.distplotでヒストグラムを描く
sns.displot(df['age'], kde=True)
#確率密度関数を除き、ヒストグラムのみを描く
sns.histplot(df['age'])
--
★注意
~/.local/lib/python3.9/site-packages/mglearn/ ディレクトリはpip3 install mglearnを実行した場合
なしのときは、introduction_to_ml_with_python/mglearnにある。
エラー表示のファイルパスをよくみること。
---------------------------------
markdown
行先頭改行1個と次の行4空白(tabキー)+テキスト、それ以降のHTML文字コードはエスケープ文字にしてくれる
その後は4空白+テキストもHTML文字コードはエスケープ文字にしてくれる
zip, pdfファイルを貼るときは,行先頭改行1個と次の行4空白でなければ、「<a href='./test.pdf'>test</a>」HTML Aタグコーディングすれば良い。
2024-11-19 「Raspberry pi OS」
□□□□□□□□□□□
2024-11-19 現在
UPDATE 2024-11-13 OS イメージ
/etc/rc.localがなくなっている。rc-localサービスもSTOPしている。
参考:https://www.cyberciti.biz/faq/how-to-enable-rc-local-shell-script-on-systemd-while-booting-linux-system/
How to enable rc.local shell script on systemd while booting Linux system
必要な場合は、
---- /etc/rc.local ----
#!/bin/sh -e
実行コマンドライン
exit 0
----
作成して、
$ sudo chmod +x /etc/rc.local
$ sudo systemctl restart rc-local
□□□□□□□□□□□
2024-10-29 現在
Raspberry pi Imagerがアップデートされている。
以前のバージョンを使ったあとは使いにくくなっている。rasbian full インストールイメージが選択できない。
2024-11-05 現在
●2024-10-22 DSKTOPイメージ
ファイルマネージャでファイルを移動、コピーしようとしてファイルのアイコンがカーソルに表示され、動作が未完だとカーソルにアイコンがついたままになる。
Rasbian OS Imagerから環境設定(パスワード、ロケール等)するとMozcがインストールされない。
ロケール設定のようにならない。
Rasbian OS Imagerからイメージコピーだけで、起動時にロケール設定が簡単。
chromium-l10nがインストールされない。
Waylandのchromiumはまだオプションなしでは日本語入力ができない。
参照:https://qiita.com/aratetsu_sp2/items/6bd89e5959ba54ede391
Bookworm (Raspberry Pi OS)のChromiumで日本語入力できない現象について
Waylandのままで、
案4 chromium-viewer --gtk-version=4
を使う。
その前にmozcを apt remove で fcitx とつくものを全部削除。
参照:https://gihyo.jp/admin/serial/01/ubuntu-recipe/0689
Ubuntu 21.10でFcitx 5を使用する
より、
$ sudo apt install fcitx5-mozc kde-config-fcitx5
$ im-config -n fcitx5
$ sudo reboot
fctix5-mozcにする。
Wayland かどうかを調べるには、
$ echo $XDG_SESSION_TYPE
でwaylandとなっている。
☆2024-07-04 bookworm Desktop イメージ
fcitx-mozcが自動インストールされた。
メニューからのOSセットアップでリモートデスクトップのセレクタボタンが追加になった。
apt updateすれば追加されている。(使う機会は今はない)
chromium-browserは日本語入力はまだできない。chromiumにすればよい。
□□□□□□□□□□□
☆2024-03-15 bookworm Desktop イメージ
$ sudo apt remove -y --purge chromium-browser
$ sudo apt remove -y --purge chromium-codecs-ffmpeg-extra
$ sudo apt install -y chromium
$ sudo apt install -y chromium-l10n
バージョアップされた。arm32 chromium バージョン: 125.0.6422.112
一時、chromium-l10nがインストールできなかったができるようになった。
Wayland で日本語入力ができるようになる。
fcitx-mozcが自動インストールされない。
☆2024-03-12 bookworm Desktop イメージ
chromium バージョン: 123.0.6312.86 にするとWayland で日本語入力ができるようになる。
いいことだ。Raspberry pi設定でブラウザの選択ができなくなっている。
スクリーンショットはgrimがインストールされている。キーprint screenでスクリーンショットされる。
slurp もインストールするとマウスで範囲指定するとその範囲がスクリーンショットされる。
fcitx-mozcが自動インストールされない。
☆2023-12-05 bookworm Desktop イメージ
raspi-configでWaylandを無効にすると、タスクバーにあるシステムアップデートアイコンに表示されるメセージが英語になる。
Waylandでは、日本語表示。
☆2023-10-10 bookworm Desktop イメージ
アクセサリimager がUPDATEされている。
機種から選択すると64ビットOSが奥の方になった。
説明書を読む人が少ないのかな?
apt updateでワーニングが出ることがある。
参考:https://github.com/MichaIng/DietPi/issues/6463
Bookworm | Mirror warnings #6463
対処方法がある。11-5現在では出ていない。
☆2023-10-10 arm32 bookworm Desktop イメージ
初回の起動OSセットアップで日本語キーボードにし、その後、raspi-configでWaylandを無効にすると、キーボードがUS配列になる。
いくら設定し直してもだめである。設定を確認しても日本語になっているのになぜ???
(通常はUS配列のキーボードを使っているのでわからなかった)
raspi-configでWaylandを有効にし直すと正常になる。
☆2023-10-10 arm64 bookworm Desktop イメージ
ブラウザが,Chromium,firefox 選択可能になっている。
Chromium バージョン: 116.0.5845.102
検索入力フィールドに日本語入力ができない。なぜ?
参照:https://qiita.com/aratetsu_sp2/items/6bd89e5959ba54ede391
Bookworm (Raspberry Pi OS)のChromiumで日本語入力できない現象について
RaspberryPi 4Bで、
chromium-viewer --ozone-platform=x11ではブラウザは開かない。
chromium-browser --ozone-platform=x11 では入力できない。
raspi-configでWaylandを無効にし、reboot後は入力できる。
Wifi 2.4Ghzの接続がよくなったような気がする。
Rasberry pi 3Bは64ビットOSで入力できる。ディスプレイのブランク黒表示は初期設定がオン。
・・・
Desktop画面がチカとフラッシュする。ディスプレイとかの環境によるかも?
OS フルバージョンはoffice,Mathematica, KiCAD付き。
ディスプレイのブランク黒表示は設定がオフなのでRaspberry Piの設定でディスプレイの画面のブランクでオン設定する。
固定IPアドレスの設定方法が変わった。
「Bookworm 固定IPアドレス設定方法」
◆方法1
タスクバーのネットワークアイコンをクリック。下のAdvanced Options選択。
「接続を編集する」でデバイスを選択して”歯車”クリック。
IPV4設定タグより、「固定IPアドレス」、「ネットマスクビット数」、「ゲートウェイ」、「DNSサーバー」
を設定。
◆方法2
参照:
https://itslinuxfoss.com/set-up-static-ip-address-debian-12-linux/
How to Set Up a Static IP Address on Debian 12 Linux
(Method2より)
(1)ネットワークデバイス接続、UUID確認
$ nmcli con show
NAME UUID TYPE DEVICE
有線接続 1 xxxxxxxx-e9e7-3d7e-xxxx-xxxxxxxxxxxx ethernet eth0
lo xxxxxxxx-ae5c-4d17-xxxx-xxxxxxxxxxxx loopback lo
(2)固定IPアドレス設定
$ sudo nmcli con mod "有線接続 1" ipv4.addresses 192.168.1.xx/24 ipv4.gateway 192.168.1.1 ipv4.dns 192.168.1.1 ipv4.method manual
(4) NetworkManager再起動
$ sudo systemctl restart NetworkManager
□□□□□□□□□□□
☆2023-05-03 bullseye Desktop イメージ
最近使わないので気が付かなかったが、bullseyeでは omxplayerがインストールされていないのに気がついた。
legacy(buster)イメージに残っている。
☆2023-05-03 arm64 bullseye Desktop イメージ
ファイルマネージャの表示とか、その他のデスクトップ表示が少し早くなった。
☆2023-02-21 イメージ
Kernel 2回めアップデートで Desktopで設定 ディスプレイ・画面のブランクが動作するようになった。
KiCadがおすすめになった。
☆2022-09-22 arm64 bullseye Desktop イメージ
最初のOS初期設定で日本を選択後、LAN接続してOSアップデートの正常終了し、リブートすると
日本語入力メソッドがfcitx-mozcインストールされる。
初のOS初期設定で日本を選択後、LAN接続してOSアップデートをしないとmozcがインストールされない。
気が付かなかった。
bullseye 32,62ビットOSのChromiumブラウザがtextarea項目にテキストをペーストし、ボタンクリックするとjavascriptに制御がうつる前に
プログラムが異常終了することがある。textareaがあるHTMLだけではないのかもしれないが。
32ビットbusterではなんともないのだけど。
2023-02-11現在。 docker make の表示が変わった。
□□□□□□□□□□□
2022-09-22 arm32 buster legacy Desktop パッケージイメージ
chromium-l10n言語パッケージを追加する。
PI-TOP V2用の電源管理・スピーカ出力モジュールを使用する場合、apt pt-hub。
sudo apt install nftables インストール。
apt pt-hubインストールしたせいかもしれないが、ファイルマネージャが固まることがある。
□□□□□□□□□□□
☆2022-09-06 arm64 bullseye Desktop イメージ
Raspberry pi 7インチディスプレイの接続は、
.....................................
参照:https://osoyoo.com/ja/2019/09/20/instruction-for-raspberry-pi-5-dsi-touch-screen/#:~:text=LCD%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%82%A4%E3%81%AE%E7%89%A9%E7%90%86%E8%A7%A3%E5%83%8F%E5%BA%A6%E3%81%AF800%C3%97480%E3%81%A7%E3%81%99%E3%80%82
Raspberry Pi 5 “DSIタッチスクリーン取扱説明書(osoyoo)
を参考に修正する。
$ sudo nano /boot/config.txt
---
#dtoverlay=cv4-fkms-V3D <<== dtoverlay=cv4-fkms-V3Dをすべてコメントにする
framebuffer_width=1200 <<== 画面大きさ
framebuffer_height=720 <<== 画面大きさ
lcd_rotate=2 <<== 回転
---
lcd_rotate=2はdtoverlay=cv4-fkms-V3Dをコメントにしないと有効にならない。
framebuffer_width, framebuffer_heightを指定すると800x480のドット数が変わる。
メールクライアントがないとき。
$ sudo apt install claws-mail
VNCクライアントがないとき。
$ sudo apt install realvnc-vnc-viewer
$ sudo apt install libreoffice
で中身がインストールされる。
iptablesが外れた。nftablesになった。systemctlで制御。
sudo apt install iptables でインストールして、iptables コマンドを実行するとnftablesに変換してくれる。
ファイルマネージャはよくなってるが、マウス右クリック コピー、マウス右クリック ペーストがちょっと仕様が変わった。
HDMIの画面の回転、サイズ変更はメインメニュー・Screen Configurationで行う。(xrandr)
.........................
コマンドラインで行うには、
回転: xrandr --output HDMI-1 --rotate right
サイズ変更(--scale): xrandr --output HDMI-1 --scale 0.7x0.7 (0.7は画素数が少なくなる)
◎コマンドを自分だけの自動実行にするには、
mkdir ~/.config/autostart
nano ~/.config/autostart/wrotate.desktop
---
[Desktop Entry]
Type=Application
Name=MyDeskTop
Exec=/home/pi/rotate.sh
--- 作成
nano ~/rotate.sh
---
#!/bin/sh
sleep 2
xrandr --output HDMI-1 --rotate right
xrandr --output HDMI-1 --scale 0.7x0.7
---作成
chmod +x rotate.sh
◎コマンドを全USERの自動実行にするには、
sudo nano /etc/xdg/autostart/mydesktop.desktop
---
[Desktop Entry]
Type=Application
Name=MyDeskTopALL
Exec=/home/pi/rotate.sh
--- 作成
実行スクリプトは上記と同じ。
メインメニュー・Main Menu Editor -> 設定 -> Desktop Session Settings(lxsession-edit)にチェックを入れる。
メインメニュー・Desktop Session Settings で[Desktop Entry]のNameで指定した名前にチェックが入ってるかを確認する。◎コマンドを自分だけの自動実行か、◎コマンドを全USERの自動実行するかのどちらかを選ぶ。
2022-08-24 「SONY Xperia Ace III SO-53C MTP接続」
https://appex.blog.fc2.com/blog-entry-64.html
Linux mint 17でのXperia XPのMTP認識
より
スマホをUSB接続(手順は選択しない)
$ lsusb
SO-53C USB IDをメモする
> Bus 001 Device 004: ID 0fce:020e Sony Ericsson Mobile Communications AB SO-53C
$ sudo nano /lib/udev/rules.d/69-libmtp.rules
SONY IDでサーチ
似たデバイスの行をコピーする
SO-53C USB IDに修正する
> # SONY Xperia Ace III (SO-53C)
> ATTR{idVendor}=="0fce", ATTR{idProduct}=="020e", SYMLINK+="libmtp-%k", MODE="660", GROUP="audio", ENV{ID_MTP_DEVICE}="1", ENV{ID_MEDIA_PLAYER}="1"
または、
「ATTR{idVendor}=="0fce", ATTR{idProduct}=="020e", SYMLINK+="libmtp-%k", MODE="660", GROUP="audio", ENV{ID_MTP_DEVICE}="1", ENV{ID_MEDIA_PLAYER}="1"」
を内容として、
$ sudo nano /etc/udev/rules.d/69-libmtp.rules
で69-libmtp.rulesファイルを作成してもよい
USBケーブルを抜く
$ sudo reboot
スマホをUSB接続し、スマホ側でUSBファイル転送にする
rasberry pi側で、リムーバブルメディア接続のウィンドウが開くのでOKをクリック
このときエラーがでる(まだ対応は調査していない、無視する)
SO-53Cディレクトリを右クリックして”ボリュームマウントを解除する”を選択
もう一度、右クリックして”ボリュームマウントする”をクリックする
内部、SDカードが表示される
それでも 「the name :n.nnnn was not provided by any .service files」メッセージが出るときは、
( https://askubuntu.com/questions/1357359/gnome-software-sorry-something-went-wrong-the-name-n-nnnn-was-not-provided-b
より)
$ sudo apt install --reinstall gnome-software
$ reboot
2021-12-31 「GITコマンド」
GITWEBインストール
$ sudo apt install apache2
$ sudo apt install gitweb
$ sudo a2enmod cgi
$ sudo adduser git
パスワード:gitdocker
$ sudo mkdir /home/git/repositories
$ sudo chown git:git /home/git/repositories
$ sudo usermod -a -G git www-data
$ sudo nano /etc/gitweb.conf
---
$projectroot = "/home/git/repositories";
$git_temp = "/tmp";
$home_link = $my_uri || "/";
$projects_list = $projectroot;
$home_link_str = "MY GIT";
$site_name = "MyGitServer WEB";
$feature{'snapshot'}{'default'} = ['zip'];
---修正
$ sudo service apache2 restart
$ ssh git@192.168.1.xx 'cd repositories;git init --bare --share project.git;echo "トラプロジェクト" > project.git/description'
$ git clone ssh://git@192.168.1.xx:/home/git/repositories/project.git
$ cd project
$ nano README.txt
$ git add .
$ git commit -m "init"
$ git push
http://192.168.1.xx/gitweb ブラウザでprojectが表示されることを確認
RAWテキスト表示の文字化け対策
$ sudo nano /usr/lib/cgi-bin/gitweb.cgi
--
our $default_text_plain_charset = 'utf-8'; <<== 修正
--
2021-09-24 「(A+B)**N の式展開」
ちょっと体操2。
(A+B)**N の数式を展開する。
nano cal_e1.py
----
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
c = [1]
d = [0] * 20
print("(A+B)**N の式展開")
print("N - in:",end="")
N = int(input().strip())
if N > 15:
N = 15
if N < 1:
N = 1
for k in range(N+1):
d[0] = 1
for i in range(k+1):
if i < k:
if i > 0:
d[i] = c[i-1] + c[i]
else:
d[i] = 1
c = d[:]
h = N // 2
print("(A+B)**%d = " % (N), end="")
for k in range(N+1):
if k == 0:
print("A**%d + " % N,end="")
elif k == N:
print("B**%d\n" % N)
elif k < h:
print("%dA**%dB**%d + " % (d[k],N-k, k),end="")
elif k <= h and (N & 1) == 0:
print("%dA**%dB**%d + " % (d[k],k, k),end="")
else:
print("%dA**%dB**%d + " % (d[k],N-k, N-(N-k)),end="")
-----
python3 cal_e1.py
.....
(A+B)**N の式展開
N - in:6
(A+B)**6 = A**6 + 6A**5B**1 + 15A**4B**2 + 20A**3B**3 + 15A**2B**4 + 6A**1B**5 + B**6
2021-08-23 「連分数」
ちょっと体操。
πとeの計算。
$ nano bun11.py
---
from decimal import *
getcontext().prec = 120
print("=== PI ===")
print("in:",end="")
N = int(input().strip())
tmp = Decimal(0)
for x in range(N, 0, -1):
tmp = Decimal(x * x) / (Decimal( 2 * x + 1 ) + tmp)
pi1000 = '3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989'
print(pi1000[:121])
print(Decimal(4.0) /(Decimal(1.0) + tmp))
print("=== e ===")
print("in:",end="")
N = int(input().strip())
tmp = Decimal(N + 1)
for x in range(N, 0, -1):
tmp = Decimal(x) + (Decimal(x) / tmp)
e1000 = '2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003059921817413596629043572900334295260595630738132328627943490763233829880753195251019011573834187930702154089149934884167509244761460668082264800168477411853742345442437107539077744992069551702761838606261331384583000752044933826560297606737113200709328709127443747047230696977209310141692836819025515108657463772111252389784425056953696770785449969967946864454905987931636889230098793127736178215424999229576351482208269895193668033182528869398496465105820939239829488793320362509443117301238197068416140397019837679320683282376464804295311802328782509819455815301756717361332069811250996181881593041690351598888519345807273866738589422879228499892086805825749279610484198444363463244968487560233624827041978623209002160990235304369941849146314093431738143640546253152096183690888707016768396424378140592714563549061303107208510383750510115747704171898610687396965521267154688957035035'
print(e1000[:121])
print(Decimal(2.0) + Decimal(1.0) / tmp)
----
$ python3 bun11.py
=== PI ===
in:155
3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664
3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664
=== e ===
in:77
2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992
2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992
.....................................
ブルーバックス 「アメリカ流 7歳からの微分積分」 ドナルドコーエン 新井紀子訳
”The Mathman”
http://mathman.biz/home.html
図:ブルーバックス 「アメリカ流 7歳からの微分積分」 ドナルドコーエン 新井紀子訳 より
2021-07-02「ジャクソン構造図」
USP MAGAZINE 2012 autumn号の「やわらかマッド~ はじめてのソフトウェア工学 第3回」を見て言語の構文解析に使えないかとヒラメキがあって興味を持った。
ジャクソン構造図はデータ構造中心でプログラムを作るものなので、言語の構文解析にも似ているかなとひらめいた。
これを使えばもっとまともな文章がひょっとしたらできるかも。
USP MAGAZINEにあったCSVファイルをやってみた。
処理中心な方向になってしまう。
参考:
(1) USP MAGAZINE Vol.5 - 2012.6月発行
やわらかマッド~ はじめてのソフトウェア工学 第2回
(2) USP MAGAZINE 2012 autumn - 2012.9月発行
やわらかマッド~ はじめてのソフトウェア工学 第3回
(3) Michael A. Jackson『構造的プログラム設計の原理』鳥居 宏次(訳)、日本コンピュータ協会、1980年。
(4) Michael Jackson『システム開発 ーJSD法ー』大野侚郎,山崎 利治(監訳)、共立出版株式会社、1989年。
JSPエディタ:
スウェーデン シェブデ大学
https://www.his.se/en/about-us/staff/henrik.engstrom/jsp-editor/
Windows users
Download the following file: jsp3.2.exe
JAVA
Download the following file: jsp3_2.jar
JAVA用をダウンロードする
使い方
$ sudo apt install openjdk-11-jdk
$ java -jar jsp3_2.jar
メニューからcで生成するとソースプログラムができる
これをPython3用に書き換える
エラー1は、 ”文字列" で終わりのダブルクォテーションがない時。
エラー2は、項目区切り文字カンマ、改行、EOFでない時。
エラー3は、文字に制御コードがあった時。
$ nano csv.py
-----
'''
int main()
{
/* Operation EOF=0 */
/* Operation レコード='' */
/* Operation get1c() */
while (!EOF){
while (c!=改行 and !EOF){
/* Operation item='' */
while (c==' ')
/* Operation Get1c() */
if (c=='"'){
/* Operation Get1c() */
while (not EOF)
if (c=='"'){
/* Operation Get1c() */
if (c=='"'){
/* Operation Get1c() */
/* Operation 文字”item追加 */
}
else
/* Operation Break */
}
else {
/* Operation 文字編集 */
/* Operation Get1c() */
}
if (EOF)
/* Operation exit(1) */
else
/* ー */
}
else
while (c!=',' and c!=改行 and !EOF){
if (c>' ')
/* Operation item文字追加 */
else
/* Operation exit(1) */
/* Operation Get1c() */
}
{
if (item=='')
/* ’_’レコード追加 */
else
/* Itemレコード追加 */
if (c==','){
/* Operation Get1c() */
/* Operation 空白区切り追加 */
}
else if (c==改行 or EOF)
/* Operation break */
else
/* Operation exit(1) */
if (EOF or c==改行)
/* Operation '_'レコード追加 */
else
/* ー */
}
}
{
/* Operation Printレコード */
if (c==改行)
/* Operation Get1c() */
else
/* EOF */
}
}
}
'''
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
EOF = 0
def getchar():
global EOF
c = sys.stdin.read(1)
if len(c) == 0:
EOF = 1
c = ''
return c
def main():
global EOF
EOF = 0
record_s = ''
c = getchar()
while not EOF:
while c!='\x0a' and not EOF:
item=''
while c==' ': # 空白削除
c = getchar()
if c=='"': # "~~~~~~"
c = getchar()
while not EOF:
if c=='"': # " "" で ”1文字
c = getchar()
if c=='"':
c = getchar()
item += '"'
else:
break # "~~~~~~" の ”終
else:
item += c # "xxxxxx" の 文字部分
c = getchar()
if EOF:
print("?Error:1> Nothing End of '\"'\n---")
print(item)
print("---")
sys.exit(1)
else:
pass
else:
while c!=',' and c!='\x0a' and not EOF:
if c>' ':
item += c # xxxxxx の 文字部分
else: # 制御文字
print("?Error:3> Invalid Code\n---")
print(item)
print("---")
sys.exit(1)
c = getchar()
if item=='': # 項目確定
record_s += '_' # Null文字
else:
record_s += item # 項目セット
if c==',': # 項目区切り文字 カンマ
c = getchar()
record_s += ' ' # 項目区切り空白セット
elif c=='\x0a' or EOF: # 項目区切り文字 改行 or EOF
break
else: # 項目区切り文字 カンマ、改行、EOF 以外
print("?Error:2> Nothing Separator ','\n---")
print(item)
print("---")
sys.exit(1)
if c=='\x0a' or EOF: # 項目区切り文字 カンマの後の文字チェック
record_s += '_'
print(record_s) # Printレコード
record_s = ''
if c=='\x0a': # 1行区切り文字 改行
c = getchar()
else: # 1行区切り文字 EOF
pass
if __name__ == "__main__":
main()
---
$ nano Book1.csv
---
a,b,c
1,2,3
"""","""""",""""""""
"""a""","""b""","""c"""
"あ
い
う",い,う
,,
,,abc
,,[EOF]
---
$ python3 csv.py < Book1.csv
...
pi@r0529rtop:~/mnt/jsp-edit $ python3 csv6.py < Book1.csv
a b c
1 2 3
" "" """
"a" "b" "c"
あ
い
う い う
_ _ _
_ _ abc
_ _ _
2021-06-13「stanford coreNLP」
Stanford CoreNLPのインストール
参考:CoreNLP を使ってみる(1)
https://lab.astamuse.co.jp/entry/corenlp1
1)環境
Raspberry pi 4B 8GB
Rasbian 2021-05-07 Desktopイメージ
2)JAVAインストール
$ sudo apt install openjdk-11-jdk
Desktopイメージではすでにインストール済。
3)Stanford CoreNLPダウンロード
https://stanfordnlp.github.io/CoreNLP/
「Download CoreNLP 4.2.2]ボタンでZIPファイルダウンロード4
4)解凍
解凍して
$ cd stanford-corenlp-4.2.2
5)corenlp.sh修正
echo java -mx2800m -cp \"$scriptdir/*\" edu.stanford.nlp.pipeline.StanfordCoreNLP $*
java -mx2800m -cp "$scriptdir/*" edu.stanford.nlp.pipeline.StanfordCoreNLP $*
--
-mx5g を -mx2800m に変更。環境によってはメモリの大きさが違うのでなるべく大きいあたいにすること。
6)センテンスパース結果の表示
パース結果がほしいので -annotators tokenize,ssplit,parse を指定。
$ ./corenlp.sh -annotators tokenize,ssplit,parse
...
NLP> Stanford University is located in California. It is a great university, founded in 1891.
Sentence #1 (7 tokens):
Stanford University is located in California.
Tokens:
[Text=Stanford CharacterOffsetBegin=0 CharacterOffsetEnd=8 PartOfSpeech=NNP]
[Text=University CharacterOffsetBegin=9 CharacterOffsetEnd=19 PartOfSpeech=NNP]
[Text=is CharacterOffsetBegin=20 CharacterOffsetEnd=22 PartOfSpeech=VBZ]
[Text=located CharacterOffsetBegin=23 CharacterOffsetEnd=30 PartOfSpeech=VBN]
[Text=in CharacterOffsetBegin=31 CharacterOffsetEnd=33 PartOfSpeech=IN]
[Text=California CharacterOffsetBegin=34 CharacterOffsetEnd=44 PartOfSpeech=NNP]
[Text=. CharacterOffsetBegin=44 CharacterOffsetEnd=45 PartOfSpeech=.]
Constituency parse:
(ROOT
(S
(NP (NNP Stanford) (NNP University))
(VP (VBZ is)
(VP (VBN located)
(PP (IN in)
(NP (NNP California)))))
(. .)))
Dependency Parse (enhanced plus plus dependencies):
root(ROOT-0, located-4)
compound(University-2, Stanford-1)
nsubj:pass(located-4, University-2)
aux:pass(located-4, is-3)
case(California-6, in-5)
obl:in(located-4, California-6)
punct(located-4, .-7)
Sentence #2 (10 tokens):
It is a great university, founded in 1891.
Tokens:
[Text=It CharacterOffsetBegin=46 CharacterOffsetEnd=48 PartOfSpeech=PRP]
[Text=is CharacterOffsetBegin=49 CharacterOffsetEnd=51 PartOfSpeech=VBZ]
[Text=a CharacterOffsetBegin=52 CharacterOffsetEnd=53 PartOfSpeech=DT]
[Text=great CharacterOffsetBegin=54 CharacterOffsetEnd=59 PartOfSpeech=JJ]
[Text=university CharacterOffsetBegin=60 CharacterOffsetEnd=70 PartOfSpeech=NN]
[Text=, CharacterOffsetBegin=70 CharacterOffsetEnd=71 PartOfSpeech=,]
[Text=founded CharacterOffsetBegin=72 CharacterOffsetEnd=79 PartOfSpeech=VBN]
[Text=in CharacterOffsetBegin=80 CharacterOffsetEnd=82 PartOfSpeech=IN]
[Text=1891 CharacterOffsetBegin=83 CharacterOffsetEnd=87 PartOfSpeech=CD]
[Text=. CharacterOffsetBegin=87 CharacterOffsetEnd=88 PartOfSpeech=.]
Constituency parse:
(ROOT
(S
(NP (PRP It))
(VP (VBZ is)
(NP
(NP (DT a) (JJ great) (NN university))
(, ,)
(VP (VBN founded)
(PP (IN in)
(NP (CD 1891))))))
(. .)))
Dependency Parse (enhanced plus plus dependencies):
root(ROOT-0, university-5)
nsubj(university-5, It-1)
cop(university-5, is-2)
det(university-5, a-3)
amod(university-5, great-4)
punct(university-5, ,-6)
acl(university-5, founded-7)
case(1891-9, in-8)
obl:in(founded-7, 1891-9)
punct(university-5, .-10)
...
7)パース結果を図にする
http://github.com/int2str/jssyntaxtree
よりダウンロード。解凍。解凍ディレクトリで
これはJAVASCRIPTで書かれた木構造を描画するもの。
そのままでは構造体の区切り文字が[]なのでこれを()に変更する。
出力された丸括弧で表示させたいので。
$ nano
----
function isControlCharacter(ch) {
const control_chars = ['[', ']','(', ')', '_', '"']; <<==()追加
return control_chars.includes(ch);
}
;;
function parseControlCharacters(input) {
if (input.charAt(0) == '_') return [new Token(TokenType.SUBSCRIPT_PREFIX), 1];
if (input.charAt(0) == '[') return [new Token(TokenType.BRACKET_OPEN), 1];
if (input.charAt(0) == ']') return [new Token(TokenType.BRACKET_CLOSE), 1];
if (input.charAt(0) == '(') return [new Token(TokenType.BRACKET_OPEN), 1]; <<==追加
if (input.charAt(0) == ')') return [new Token(TokenType.BRACKET_CLOSE), 1]; <<==追加
return [null, 0];
}
---- 修正
解凍ディレクトリでpythonサーバを起動。
$ python3 -m http.server 8000
WEBブラウザで
http://localhost:800
で開く。
上のテキストフィールドに
「(ROOT
(S
(NP (NNP Stanford) (NNP University))
(VP (VBZ is)
(VP (VBN located)
(PP (IN in)
(NP (NNP California)))))
(. .))) 」
コピー&ペーストする。
図を木リックすると画像がダウンロードされる。
2021-04-30 「TinyBasic Plus for PICO」
RP2040の周辺デバイスレジスタを直接読み書きしたくてBASICを移植してみた。
BASICソースプログラムは最近の流行からはそれている。
FATFSはプログラムをSAVE,LOADするのに必要なので追加した。長いファイル名、日本語ファイル名可。
EDITORは小さくてTTYエスケープシーケンスを使うものを探して移植。
Download Files
(1) http://elm-chan.org/fsw/ff/00index_e.html
FatFs - Generic FAT Filesystem Module
FatFs sample projects for various platforms (December 5, 2020)
http://elm-chan.org/fsw/ff/ffsample.zip
FM3を参考にする。
(2) https://github.com/BleuLlama/TinyBasicPlus
TinyBasic Plus
https://github.com/BleuLlama/TinyBasicPlus/archive/refs/heads/master.zip
(3) https://github.com/GrenderG/tte
tte (tiny text editor)
https://github.com/GrenderG/tte/archive/refs/heads/master.zip
(4) https://www.raspberrypi.org/documentation/rp2040/getting-started/
Raspberry pi PICO
https://datasheets.raspberrypi.org/pico/getting-started-with-pico.pdf
Getting started with Raspberry Pi Pico
(5) getting-started-with-pico.pdfの説明によりインストールする。
できた "~/pico"ディレクトリにTBASIC PLUSのzipファイルを解凍する。
Cmakeか、VSCODEでコンパイルする。
▶VSCODE設定
$ code --install-extension marus25.cortex-debug
$ code --install-extension ms-vscode.cmake-tools
$ code --install-extension ms-vscode.cpptools
PICO_SDK_PATH は設定されている。
.vscode/launch.jsonの修正
□pico-examplesをコンパイルとデバッグする場合
$ cd pico/pico-examples
$ mkdir .vscode
$ cp ide/vscode/launch-raspberrypi-swd.json .vscode/launch.json
$ cp ide/vscode/settings.json .vscode
■他のプログラムの場合
$ cd pico/tbasic_fatfs
自分で作成したプロジェクトのディレクトリ
$ cp ../pico-examples/ide/vscode/launch-raspberrypi-swd.json .vscode/launch.json
$ cp ../pico-examples/ide/vscode/settings.json .vscode
◎共通 コピーしたlaunch.json修正
$ nano .vscode/launch.json
---
{
"version": "0.2.0",
"configurations": [
{
"name": "Pico Debug",
"cwd": "${workspaceRoot}",
"executable": "${command:cmake.launchTargetPath}",
"request": "launch",
"type": "cortex-debug",
"servertype": "openocd",
// This may need to be arm-none-eabi-gdb depending on your system
"gdbPath" : "gdb-multiarch",
"device": "RP2040",
"configFiles": [
"interface/picoprobe.cfg", <<===raspberrypi-swd.cfg をpicoprobe.cfgに変更
"target/rp2040.cfg" (picoprobeを使う場合)
],
"svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",
"runToMain": true,
// Work around for stopping at main on restart
"postRestartCommands": [
"break main",
"continue"
]
}
]
}
----
ソースプログラムダウンロード tbasic-fatfs.zip(759Kb)
......
BASIC言語
- BYE - *exits Basic, soft reboot on Arduino*
- END - *stops execution from the program, also "STOP"*
- MEM - *displays memory usage statistics*
- NEW - *clears the current program*
- RUN - *executes the current program*
- FILES - *lists the files on the SD card*
- LOAD "filename.bas" - *new and loads a file from the SD card*
- ALOAD "filename.bas" - *overwrite and loads a file from the SD card and auto restart
- SAVE "filename.bas" - *saves the current program to the SD card, overwriting*
- INPUT variable - *let the user input an expression (number or variable name*
- PEEK( address ) - *get a value in memory* (unimplemented)
- POKE address - *set a value in memory* (unimplemented)
- PRINT expression - *print out the expression, also "?"*
- REM stuff - *remark/comment, also "'"*
- IF expression statement - *perform statement if expression is true*
- FOR variable = start TO end - *start for block*
- FOR variable = start TO end STEP value - *start for block with step*
- NEXT - *end of for block*
- GOTO linenumber - *continue execution at this line number*
GOTO 100, GOTO A + 10
- GOSUB linenumber - *call a subroutine at this line number*
GOSUB 100, GOSUB A + 10
- RETURN - *return from a subroutine*
- SLEEP msec - *wait 99 msec
- SETRC "yyyy/mm/dd hh:mm:ss" - *Set to RTC
- !xxxx - *command for Fatfs
(o)Expressions, Math
- A=V, LET A=V - *assign value to a variable*
- +, -, %, &, *, / - *Math*
- <,<=,=,<>,!=,>=,> - *Comparisons*
- ABS( expression ) - *returns the absolute value of the expression*
- RSEED( v ) - *sets the random seed to v*
- RND( m ) - *returns a random number from 0 to m*
(o)Function
- RDATE() - *Read Date from RTC
- RTIME() - *Read Time from RTC
Tiny BASIC Plus追加機能
・演算子 % :MOD 5 % 6 * 8 = 5 :*優先 MBASIC80と同様 5 % (6*8) 、C言語とは違う (5 % 6) * 8
・演算子 & :AND 10 & 3 = 2 : *,/ 優先
・16進数表現 $hhhh : 定数
$PEEK(a) : 関数戻り値の16進数表示
$A : 変数の16進数表示
・関数追加 RDATE() : RTC日付取得 戻り値 (y*256*16 + m*256 + day)
RTIME() : RTC時刻取得 戻り値 (hh*256*256 + mm*256 + ss)
・ステートメント追加
SLEEP msec : ミリ秒で指定
SETRTC "yyyy/mm/dd hh:mm:ss" : RTCに年月日時刻を設定する。
年/月/日 時:分:秒の文字列で指定
ADDA A, 1 : 変数をアドレス値(unsigned long)で加算する。減算はマイナス値を加算する。
ALOAD "プログラムファイル名" : 現在のプログラムに追加または、上書きロードされる。
ロード後はメモリされたプログラムの行番号が一番小さい行から実行される。
FILES ["ディレクトリ[/ディレクトリ]”]: SDカード内のファイル一覧
・文字列のエスケープシーケンス追加
\\ = \文字 、\' = '文字 , \" = "文字
\888 = 8進数で文字コード表現
・変数を32ビットで扱う。
・BASICステートメント1行を400文字に制限。
・PEEK,POKEを8ビットか、32ビットで扱うか指定可能。
PEEK(A) : 8ビット扱い
PEEK(A#) : 32ビット扱い、このときアドレスは4の倍数のこと。
POKE A, 10 : 8ビット扱い
POKE A, 10# : 32ビット扱い、このときアドレスは4の倍数のこと。
・行番号 1 ~ 65533
・FATFSファイル管理コマンド実行
BASICコマンド入力で先頭に"!"を入力する。
!mount <-- SDカードを抜き差しした後で必ず実行。
!type "ファイル名Path" <-- ファイル内テキスト表示。
!mkdir "ディレクトリ名" <-- ディレクトリ作成
!rmdir "ディレクトリ名" <-- ディレクトリ削除
!rm "ファイル名" <-- ファイル削除
!cp "コピー元ファイル名" "コピー先ファイル名" <-- ファイルコピー
!edit ["ファイル名"] <-- テキストファイル編集
Keybinding Action
Ctrl-Q Exit
Ctrl-S Save
Ctrl-F Search. Esc, enter and arrows to interact once searching
Ctrl-E Flip line upwards
Ctrl-D Flip line downwards
Ctrl-C Copy line
Ctrl-X Cut line
Ctrl-V Paste line
Ctrl-Z Undo
Ctrl-Y Redo
Ctrl-A Help
... 注意 ...
端末ターミナルウィンドウは80桁24行固定。
これより小さい場合はカーソル制御が正しくできなくなるので編集ができなくなる。
矢印キー等の複数コードが生成されるキーの長押しはキーコードの取りこぼしが起きるので注意すること。
UTF-8日本語は可変長複数コードとなるので編集する場合はただの1バイトコードとして扱うので文字化けが
起きることがあるので注意する。また、行内の日本語以降カーソル位置がバイト位置なので文字削除挿入は
注意すること。80桁目にあるものと、横スクロールした場合は1桁目にある日本語は文字化けする。
1行は500バイトまで。
編集できるサイズはおおよそ空きメモリ未満。
(注意1)
BASIC文入力中、行が折り返した場合、バックスペースでは前の行の後ろ側には回り込まない。
端末の横幅を調整しながら前の行に回り込まないようにする。
RTCは何もしないと"2021/4/1 00:00:00"から動作している。ファイルのタイムスタンプにも使用。
メモリがないところ等にアクセスするとHARDFAULTとなるのでPEEK,POKEは注意すること。
アドレスチェックは32ビットアクセスの4バイト倍数以外はしていなのでメモリアドレスに書き込みした場合は
動作はどうなるかは不明。RP2040データシートをよく読むこと。
(注意2)
GPIO 25はBASIC,EDITORで使用しているのでBASICでは使用しないこと。
GPIO 25 LED不規則点滅:FatFS,BASIC、EDITOR動作中。
GPIO 25 LED等間隔点滅:FatFS,BASIC、EDITOR動作中にHARDFAULTが発生。リセット、電源入れ直す。
GPIO 25 LED消灯:BASIC動作中にBYEコマンド入力した。リセット、電源入れ直す。
FATFS追加
プログラムセーブ、ロード用
FAT32 SDカード対応
UTF-8ファイル名対応
ファイル名パスは,130文字まで。
cd, pwd カレントディレクトリという操作はない。
mkdir xxx, mkdir xx/xxx はあり。
files "xxx", files "xxx/xxxx" はあり。
参考:メモリ容量
[build] Memory region Used Size Region Size %age Used
[build] FLASH: 189380 B 2 MB 9.03%
[build] RAM: 80184 B 256 KB 30.59%
[build] SCRATCH_X: 0 GB 4 KB 0.00%
[build] SCRATCH_Y: 0 GB 4 KB 0.00%
端末ターミナルソフトはminicom だと日本語が文字化けする。
cuかckermitがよい。
├── CMakeLists.txt :Cmake 情報ファイル
|
├── README.txt :説明
├── TinyBasicPlus <dir> :TINY BASIC PLUSソース
│ ├── FILE-LIST
│ ├── README.md
│ ├── TinyBasicPlus.ino
│ ├── TinyBasicPlus_main.c
│ ├── desktop.h
│ └── main.cpp
├── build <dir> :プログラムビルドディレクトリ
│ ├── CMakeCache.txt
│ ├── CMakeFiles <dir>
│ ├── Makefile : Makefile
│ ├── cmake_install.cmake
│ ├── compile_commands.json
│ ├── elf2uf2 <dir>
│ ├── generated <dir>
│ ├── pico-sdk <dir>
│ ├── tbasic_fatfs.bin
│ ├── tbasic_fatfs.dis
│ ├── tbasic_fatfs.elf
│ ├── tbasic_fatfs.elf.map :リンクマップ
│ ├── tbasic_fatfs.hex
│ └── tbasic_fatfs.uf2 :BOOTSELスイッチを押して書き込みするファイル
├── fatfs <dir> :FATFS, Raspberry pi PICO基板の依存する関数プログラムファイル
│ ├── Ev_Board.c
│ ├── Ev_Board_conf.h
│ ├── fatfs <dir>
│ │ ├── diskio.h
│ │ ├── ff.c
│ │ ├── ff.h
│ │ ├── ffsystem.c
│ │ └── ffunicode.c
│ ├── ffconf.h
│ └── mmc_mfs.c
├── pico_sdk_import.cmake
├── tbasic_fatfs.c :Tiny Basic Plus mainプログラム
└── tte <dir> :EDITORプログラム
├── LICENSE
├── README.md
└── tte.c
ファイル:CMakeLists.txt
...
# Generated Cmake Pico project file
cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
# initalize pico_sdk from installed location
# (note this can come from environment, CMake cache etc)
set(PICO_SDK_PATH "/home/pi/pico/pico-sdk")
# Pull in Raspberry Pi Pico SDK (must be before project)
include(pico_sdk_import.cmake)
project(tbasic_fatfs C CXX ASM)
# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()
# Add executable. Default name is the project name, version 0.1
add_executable(tbasic_fatfs
fatfs/Ev_Board.c
fatfs/fatfs/ff.c
fatfs/fatfs/ffsystem.c
fatfs/mmc_mfs.c
fatfs/fatfs/ffunicode.c
tbasic_fatfs.c
TinyBasicPlus/TinyBasicPlus_main.c
tte/tte.c )
pico_set_program_name(tbasic_fatfs "tbasic_fatfs")
pico_set_program_version(tbasic_fatfs "0.1")
pico_enable_stdio_uart(tbasic_fatfs 0) <<--USB ACM UARTを使うとき
pico_enable_stdio_usb(tbasic_fatfs 1) <<--
#pico_enable_stdio_uart(tbasic_fatfs 1) <<==GPIO1,2 UARTを使うとき
#pico_enable_stdio_usb(tbasic_fatfs 0) <<==
# Add the standard library to the build
target_link_libraries(tbasic_fatfs pico_stdlib)
# Add any user requested libraries
target_link_libraries(tbasic_fatfs
hardware_spi
hardware_pwm
hardware_rtc
)
pico_add_extra_outputs(tbasic_fatfs)
include_directories(./ ./fatfs ./fatfs/fatfs)
#add_definitions(-DRASPI_PICO -DDDEBUG ) <<==SDカードCDピンがカード挿入時HI Activeのとき
DDEBUGマクロが要らない時は -DDDEBUG削除。
add_definitions(-DRASPI_PICO -DAKDK_SOCKET) <<--SDカードCDピンがカード挿入時LOW Activeのとき
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--print-memory-usage")
...
◎配線
picoprobeとDEBUG対象PICOボード配線
picoprobe GND -> Pico B GND
picoprobe GP2 -> Pico B SWCLK
picoprobe GP3 -> Pico B SWDIO
picoprobe GP4/UART1 TX -> Pico B GP1/UART0 RX
picoprobe GP5/UART1 RX -> Pico B GP0/UART0 TX
picoprobe VSYS -> Pico B VSYS
(getting-started-with-pico.pdf Appendix A: Using Picoprobe の Picoprobe Wiring 参照)
sparkfun.con micro-SD-card board
Pico B GPIO 16 (pin 21) MISO/spi0_rx-> DO on SD-card board
Pico B GPIO 17 (pin 22) Chip select -> CS on SD-card board
Pico B GPIO 18 (pin 24) SCK/spi0_sclk -> SCK on SD-card board
Pico B GPIO 19 (pin 25) MOSI/spi0_tx -> DI on SD-card board
Pico B GPIO 22 (pin 29) GPIO -> CD on SD-card board
Pico B 3.3v (pin 36) -> VCC on SD-card board
Pico B GND (pin 38) -> GND on SD-card board
SDカードCDがどちらがActiveかをチェックするプログラム
GPIO 22を見ている。
SDカードを抜き差しして確認する。
-----
10 A = PEEK($D0000004#)
20 IF (A & $400000) != 0 GOTO 50
30 PRINT "SD CS検出LOW"
40 GOTO 60
50 PRINT "SD CS検出HI"
60 SLEEP 500
61 FILES
70 GOTO 10
-----
>mem
Program Start: h'20003570
Start Free Memory: h'20003570 - End Free Memory: h'2001344F
65248 bytes free.
pokeステートメントはmemで表示される空きメモリアドレスの間に指定する。
peek, pokeで指定するアドレスは空きメモリアドレス以外でも可能であるが、CPU Hardfault エラーになるか、
全体が動作不可能、不安定等になる場合がある。Hardfaultについては基板上のLEDが等間隔で点滅する。
このときはCPUをリセットすること。
>load "memdump.bas"
OK
>list
100 A = $20007CF0
110 B = $20007D30
120 POKE A, $EE
130 ADDA A, 1
140 IF A != B GOTO 120
200 GOSUB 8000
210 POKE $20007D04, 12345678#
220 POKE $20007D02, 12345678
230 POKE $20007D14, $12345678#
240 POKE $20007D12, $12345678
300 GOSUB 8000
310 END
8000 A = $20007CF0
8001 B = $20007D30
8002 PRINT "___ADDRESS_:_DATA___________________________________"
8004 PRINT ########.$A," : ";
8010 PRINT ##.$PEEK(A)," ";
8012 ADDA A, 1
8014 IF A = B GOTO 8050
8020 IF ( A % 8 ) != 0 GOTO 8040
8022 PRINT " "
8024 PRINT ########.$A," : ";
8040 GOTO 8010
8050 PRINT ""
8060 RETURN
OK
>run
___ADDRESS_:_DATA___________________________________
h'20007CF0 : h'EE h'EE h'EE h'EE h'EE h'EE h'EE h'EE
h'20007CF8 : h'EE h'EE h'EE h'EE h'EE h'EE h'EE h'EE
h'20007D00 : h'EE h'EE h'EE h'EE h'EE h'EE h'EE h'EE
h'20007D08 : h'EE h'EE h'EE h'EE h'EE h'EE h'EE h'EE
h'20007D10 : h'EE h'EE h'EE h'EE h'EE h'EE h'EE h'EE
h'20007D18 : h'EE h'EE h'EE h'EE h'EE h'EE h'EE h'EE
h'20007D20 : h'EE h'EE h'EE h'EE h'EE h'EE h'EE h'EE
h'20007D28 : h'EE h'EE h'EE h'EE h'EE h'EE h'EE h'EE
___ADDRESS_:_DATA___________________________________
h'20007CF0 : h'EE h'EE h'EE h'EE h'EE h'EE h'EE h'EE
h'20007CF8 : h'EE h'EE h'EE h'EE h'EE h'EE h'EE h'EE
h'20007D00 : h'EE h'EE h'4E h'EE h'4E h'61 h'BC h'00
h'20007D08 : h'EE h'EE h'EE h'EE h'EE h'EE h'EE h'EE
h'20007D10 : h'EE h'EE h'78 h'EE h'78 h'56 h'34 h'12
h'20007D18 : h'EE h'EE h'EE h'EE h'EE h'EE h'EE h'EE
h'20007D20 : h'EE h'EE h'EE h'EE h'EE h'EE h'EE h'EE
h'20007D28 : h'EE h'EE h'EE h'EE h'EE h'EE h'EE h'EE
OK
>load "vect-dump.bas"
OK
>list
10 PRINT "Vector Table Offset:",$PEEK($E000ED08#)
20 A = PEEK($E000ED08#)
30 FOR I = -16 TO 31
40 IF I < 0 PRINT ##.I;
41 IF I >= 0 PRINT ###.I;
42 PRINT " [ ",########.$A," ] = ",########.$PEEK(A#)
50 ADDA A, 4
60 NEXT I
OK
>run
Vector Table Offset:h'20000000
-16 [ h'20000000 ] = h'20042000
-15 [ h'20000004 ] = h'100001F7
-14 [ h'20000008 ] = h'100001C3
-13 [ h'2000000C ] = h'100004E1
-12 [ h'20000010 ] = h'100001C1
-11 [ h'20000014 ] = h'100001C1
-10 [ h'20000018 ] = h'100001C1
-09 [ h'2000001C ] = h'100001C1
-08 [ h'20000020 ] = h'100001C1
-07 [ h'20000024 ] = h'100001C1
-06 [ h'20000028 ] = h'100001C1
-05 [ h'2000002C ] = h'100001C7
-04 [ h'20000030 ] = h'100001C1
-03 [ h'20000034 ] = h'100001C1
-02 [ h'20000038 ] = h'100001C9
-01 [ h'2000003C ] = h'100001CB
000 [ h'20000040 ] = h'100001CD
001 [ h'20000044 ] = h'100001CD
002 [ h'20000048 ] = h'100001CD
003 [ h'2000004C ] = h'1000D6E9
004 [ h'20000050 ] = h'100003F9
005 [ h'20000054 ] = h'10011E4D
006 [ h'20000058 ] = h'100001CD
007 [ h'2000005C ] = h'100001CD
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
029 [ h'200000B4 ] = h'100001CD
030 [ h'200000B8 ] = h'100001CD
031 [ h'200000BC ] = h'10011C49
OK
>load "pwmreg-lst.bas"
OK
>list
10 PRINT "=== PWM Registers List ==="
20 A =$40050000
30 FOR I = 0 TO 44
40 IF (I / 5) != 8 GOTO 80
50 IF (I % 5) != 0 GOTO 90
60 PRINT " ......"
70 GOTO 90
80 IF (I % 5) = 0 PRINT " ... PWM ",I/5," ..."
90 IF I < 0 PRINT ##.I;
100 IF I >= 0 PRINT ###.I;
110 PRINT " [ ",########.$A," ] = ",########.$PEEK(A#)
120 ADDA A, 4
130 NEXT I
OK
>run
=== PWM Registers List ===
... PWM 0 ...
000 [ h'40050000 ] = h'00000000
001 [ h'40050004 ] = h'00000010
002 [ h'40050008 ] = h'00000000
003 [ h'4005000C ] = h'00000000
004 [ h'40050010 ] = h'0000FFFF
... PWM 1 ...
005 [ h'40050014 ] = h'00000000
006 [ h'40050018 ] = h'00000010
007 [ h'4005001C ] = h'00000000
008 [ h'40050020 ] = h'00000000
009 [ h'40050024 ] = h'0000FFFF
... PWM 2 ...
010 [ h'40050028 ] = h'00000000
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
017 [ h'40050044 ] = h'00000000
018 [ h'40050048 ] = h'00000000
019 [ h'4005004C ] = h'0000FFFF
... PWM 4 ...
020 [ h'40050050 ] = h'00000001
021 [ h'40050054 ] = h'00000640
022 [ h'40050058 ] = h'000002E6
023 [ h'4005005C ] = h'000C0000
024 [ h'40050060 ] = h'000004E1
... PWM 5 ...
025 [ h'40050064 ] = h'00000000
026 [ h'40050068 ] = h'00000010
027 [ h'4005006C ] = h'00000000
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
033 [ h'40050084 ] = h'00000000
034 [ h'40050088 ] = h'0000FFFF
... PWM 7 ...
035 [ h'4005008C ] = h'00000000
036 [ h'40050090 ] = h'00000010
037 [ h'40050094 ] = h'00000000
038 [ h'40050098 ] = h'00000000
039 [ h'4005009C ] = h'0000FFFF
......
040 [ h'400500A0 ] = h'00000010
041 [ h'400500A4 ] = h'00000000
042 [ h'400500A8 ] = h'00000010
043 [ h'400500AC ] = h'00000000
044 [ h'400500B0 ] = h'00000000
OK
>load "hex-t01.bas"
OK
>list
10 PRINT $$1234
20 PRINT ####.$$1234
30 PRINT ###.$$CD
40 PRINT ###.$$ABCD
50 A = $4567
60 PRINT ###.$A
70 PRINT ######.$A
OK
>run
h'1234
h'1234
h'0CD
h'ABCD
h'4567
h'004567
OK
>load "num-t01.bas"
OK
>list
10 PRINT 1234
20 PRINT ######.1234
30 PRINT ###.34
40 PRINT ###.1234
50 PRINT ##12, "=NG"
OK
>run
1234
001234
034
1234
What? 50 PRINT ##^2, "=NG"
>load "esc-t01.bas"
OK
>list
10 PRINT "\033[A\033[ATEST 001"
20 PRINT "\377[A", "OK"
30 PRINT "\\015[A","OK"
40 PRINT "\"015[A","OK"
50 PRINT "data\"abc","OK"
60 PRINT "data\'abc"," OK"
70 PRINT "data'abc"," OK"
80 PRINT 'data\'abc'," OK"
90 PRINT 'data\"abc'," OK"
100 PRINT 'data"abc'," OK"
110 PRINT "\029[A","NG"
120 PRINT "\097[A","NG"
130 PRINT "\477[A","NG"
TEST 001
\ufffd[AOK
\015[AOK
"015[AOK
data"abcOK
data'abc OK
data'abc OK
data'abc OK
data"abc OK
data"abc OK
What? 110 PRINT "^029[A","NG"
ーーー
TinyBasic,FatFs用にPWM4をタイマー用に使いGPIO-25の基板についているLEDを点滅させている。
>load "gpio-test.bas"
OK
>list
10 REM **** GPIO-02 LED ON/OFF 500 USEC INTERVAL
20 Z = 500
30 GOSUB 1000
40 GOSUB 3000
50 GOSUB 4000
60 GOSUB 2000
70 GOTO 50
1000 POKE $E000E010, 1#
1010 POKE $E000E014, Z#
1020 POKE $E000E018, 0#
1030 Z = PEEK($E000E010#)
1040 RETURN
2000 Z = PEEK($E000E010#)
2010 IF (Z & $010000) = 0 GOTO 2000
2020 RETURN
3000 POKE $40014014, 5#
3010 POKE $D0000020, 4#
3020 RETURN
4000 POKE $D000001C, 4#
4010 RETURN
OK
>run
break!
OK
ーーー
よくあるLED点滅。Systickタイマを使う。
配線 LED
GPIO-02 --/\/\510Ω/\/\/---▶|---> GND
目視では点灯
20 Z = 数字 :数字20000以上で点滅して見える。
>setrtc "2021/4/28 14:01:00"
>load "date.bas"
OK
>list
10 PRINT "\012\012\012"
20 REM SETRTC "2021/4/3 11:59:40"
30 A = RTIME()
40 B = RDATE()
50 PRINT "\015\012\012\033[4A",(B&$FFFF000)/(256*16),"年",##.(B&$F00)/256,"月",##.B%256,"日"
60 PRINT ##.(A&$FF0000)/(256*256),":",##.(A&$FF00)/256,":",##.A%256
70 PRINT "\012\012"
80 SLEEP 1000
90 PRINT "\033[4A"
100 GOTO 30
OK
>run
2021年04月28日
14:01:32
break!
OK
>!type "ald00.bas"
10 PRINT "10"
20 PRINT "20"
30 PRINT "30"
40 A = 1
50 ALOAD "ald01.bas"
300 print "SUB 300 : ", A
310 A = A + 1
320 IF A > 5 END
330 SLEEP 500
340 RETURN
>!type "ald01.bas"
10 GOSUB 300
20 PRINT "100"
30 PRINT "110"
40 ALOAD "ald02.bas"
>!type "ald02.bas"
10 GOSUB 300
20 PRINT "80"
30 PRINT "90"
40 ALOAD "ald01.bas"
>load "ald00.bas"
OK
>run
10
20
30
SUB 300 : 1
100
110
SUB 300 : 2
80
90
SUB 300 : 3
100
110
SUB 300 : 4
80
90
SUB 300 : 5
OK
>load "goto.bas"
OK
>list
10 FOR I = 0 TO 14
20 GOTO (I%5)*10+30
30 PRINT "*";
40 PRINT "*";
50 PRINT "*";
60 PRINT "*";
70 PRINT "*"
200 NEXT I
OK
>run
*****
****
***
**
*
*****
****
***
**
*
*****
****
***
**
*
OK
2021-03-30 「CP/M エミュレータ」
raspberry pi PICOにTiny BASICを入れようと思ったのが原因で横道にそれてしまった。
参照:
YAZE-AG - Yet Another Z80 Emulator by AG (V 2.40.5 / V 2.30.3)
http://www.mathematik.uni-ulm.de/users/ag/yaze-ag/
(1)インストール
$ wget http://www.mathematik.uni-ulm.de/users/ag/yaze-ag/devel/yaze-ag-2.40.5_with_keytrans.tar.gz
$ tar zxvlpf yaze-ag-2.40.5_with_keytrans.tar.gz
$ cd yaze-ag-2.40.5_with_keytrans
$ cp Makefile_Raspberry_Pi_3_Model_B_ARMv7_32Bit Makefile
$ make -j 4
$ sudo make install
$ cd ~
$ rm -r yaze-ag-2.40.5_with_keytrans
$ rm -f yaze-ag-2.40.5_with_keytrans.tar.gz
$ man yaze
$ yaze cpm (CP/Mが動く)
~/cpm ディレクトリが出来る。
ドライブがWrite可能かどうかの一覧
各ドライブにソフトが入っている。
A: r/w BOOT_UTILS BOOT disk with CCP.COM and some utilies
B: r/w CPM3_SYSdsk Disk with all CP/M 3.1 system utilities
A section "YAZE-AG" is added in the help file.
C: r/o ./disksort/ Connected to the (unix-)directory ./disksort/ (SOURCE)
D: r/w DISKSORT.dsk Submit examples of the DISKSORT project
F: r/w ZINC System Utilies of the ZINC project from John Elliott
G: r/w TEST-UTILS-1.10 Test Utilities of the old version yaze-1.10
H: r/w HI-C-Z280-Compiler A Copy of the C Compiler from HI Tech Soft
I: r/w UNIXLIKE UNIX like utilities
J: r/w MMU-Utils Testfiles for the Memory Management Unit (MMU).
K: r/w Kermit_SZRZ.ydsk Kermit and SZ/RZ (Zmodem)
L: r/w spl.ydsk SPL development environment to compile .SPL files
M: r/w Turbo-Modula-2 Modula 2 Compiler of Borland
N: r/w testdsk.ydsk testdisk
P: r/w BIOS3 Sources of the BIOS3 for YAZE-AG (look 0-README.1ST)
ファイルコピー
D> pip コピー先ファイル名=コピー元ファイル名
D> pip con:=ファイル名 (画面表示)
D> pip aux:=ファイル名 (シリアルへ)
アセンブラ
D> mac ファイル名[.asm]
D> hexcom ファイル名[.hex] (HEXからCOMファイルへ変換)
UNIXコマンド
A> df (マウント全ドライブの容量表示)
A> i:ls *.* -f
kermitでシリアル経由で接続する
$ cd ~/cpm
$ nano .yazerc
----
attach aux /dev/ttyUSB1
---- 環境によるターミナルに合わせること(UNIX端末ポートをCP/M COMポートに割り当てる)
$ stty -F /dev/ttyUSB1 -crtscts raw 115200 (ttyをRAWモード、ハンドシェークなし、BPSを設定する)
$ yaze cpm
x> k:
k> kermit
(/home/pi/cpm) C-Kermit> remote dir (リモート側KERMITでls結果が表示)
(/home/pi/cpm) C-Kermit> send ファイルパス (ファイル送信)
(/home/pi/cpm) C-Kermit> get リモートファイルパス (ファイル受信)
linux側KERMITをサーバにする
--- ~/.kermrc ------
set line /dev/ttyUSB0
set carrier-watch off
set speed 115200
set parity none
set flow-control none
set escape-character ^]
server
-----------------
$ nano kerm_server.sh
--------------------
#!/bin/sh
DEV=/dev/ttyUSB0
stty -F $DEV -crtscts raw 115200
kermit
----------作成
$ chmod +x kerm-server.sh
$ ./kerm-server.sh
kermitがサーバモードで動作
rz, szコマンドを使う時
LINUX側
----send---
#!/bin/sh
DEV=/dev/ttyUSB0
stty -F $DEV -crtscts raw 115200
sz $1 > $DEV < $DEV
----
-----recieve---
#!/bin/sh
DEV=/dev/ttyUSB0
stty -F $DEV -crtscts raw 115200
rz $1 > $DEV < $DEV
-----
CP/Mの終了
A> sys[enter]
CP/Mエミュレータの終了
$> quit[enter]
CP/Mエミュレータのヘルプ
$> help (コマンド一覧)
$> help コマンド (コマンドオプションの説明)
ドライブの追加
$ cdm
$> create XXXXX.ydsk 256KB (容量を指定、なしは1MB)
$> quit
$ cdm XXXXX.ydsk
A0> ls -l (ファイル一覧)
A0> cp u:UNIXファイル名 CP/Mファイル名 (バイナリ転送、t:xxxはテキスト転送)
A0> cp CP/Mファイル名 u:UNIXファイル名
A0> quit
$ nano ~/cpm/.yazerc
------
mount o XXXXX.ydsk
----追加
容量が大きいと"insufficient space to mount XXXXX.ydsk"メッセージがコマンド入力直後に表示される。
~/cpm/.yazercファイルの"go"コマンドをコメントにしてチェックすると良い。
デフォルトでは"E","O"ドライブが空き。いらないのを外せば容量が大きくできる。
最大16ドライブまでマウント出来る。
2021-06-04 「Raspberry pi PICO」
どんなものかと1個買ってみました。
ほぼ裸でです。
書き込みは、mbedかMicro:bitみたいな感覚です。
Micro:bitはUSBシリアル・フラッシュ書き込みは別CPUなのが、PICOはファームウェアでCPUひとつでやっている。
参照:getting-started-with-pico.pdf (2021-03-05)
raspberry-pi-pico-python-sdk.pdf (2021-03-05)
hardware_design_with_rp2040.pdf (2021-03-05)
pico_c_sdk.pdf (2021-03-05)
(1)開発環境
Raspberry pi 4B+ 4GB
(2)OSインストール
Raspberry pi 2021-01-11 Desktopイメージインストール
sudo apt install fcitx-mozc
sudo nano /boot/config.txt
---
hdmi_force_hotplug=1
---追加,コメントを外す
VNCを有効
画面の大きさ変更は、VNC接続後に"メニュー設定"ー>"Screen Configuration"で行う。
(3)picoツールインストール
wget https://raw.githubusercontent.com/raspberrypi/pico-setup/master/pico_setup.sh
chmod +x pico_setup.sh
./pico_setup.sh
sudo reboot
minicomは一緒にインストールされる
(4)VSCodeで開発はツールインストールでインストール済なのでメニューから起動できる。
オープンフォルダで "~/pico/pico-examples" を開くとコンパイルできる。
(5)配線
Raspberry pi GPIO14 --- PICO pin2(GP1)
Raspberry pi GPIO15 --- PICO pin1(GP0)
Raspberry pi GND --- PICO pin3(GND) に接続。
Raspberry pi GPIO24 --- PICO SWDIO
Raspberry pi GPIO25 --- PICO SWCLK
Raspberry pi GND --- PICO SWDGND に接続。
Raspberry pi 5V --- ショットキダイオードー▶ー --- PICO VSYS
プログラムをフラッシュに書き込んで、電源を外部からVSYS,またはUSBから給電する場合に周辺回路の電源を3v3ピン
からとるようなことをした場合にリセットがうまく行かない場合がある。
その時はRUNピンをGNDにする。または、RUN pin(37)とGND間に10μF電解コンデンサを入れて RUN pin(37)と3v3(36)に
ダイオードを入れる。向きは3v3(36)pin方向にコンデンサが放電するような向きに入れる。
少電力ダイオード
↓
(36)3v3(OUT) --|◀--+---RUN pin(37)
|
---- +
//// 10uF (電解コンデンサ)
---- -
|
▽ GND
(6)VisualStudio-Code と OPENOCDでデバッグ
これでデバッグできるのだが、OSをアップデートしたか何かでできなくなってしまった。
フラッシュイレースができないとなる。
そこでpicoprobeでやることにした。Raspberry Pi PICOを1枚picoprobeにする。
開発環境ボードとはUSBケーブルで接続する。
picoprobeはツールインストールで作成されているのでそのuf2ファアイルをUSB経由で書き込む。
(7)USB picoprobeのパーミッションの変更
sudo nano /etc/udev/rules.d/98-p-probe.rules
---
ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0004", MODE="0666"
---作成
USBベンダーとプロダクトはlsusbコマンドで表示されるもの。
”Bus 001 Device 003: ID 2e8a:0004”
作成したら、リブートして有効にすること。
有効にしないとコンパイルはできるがデバッグができない。
(8)picoprobeとDEBUG対象PICOボード配線
picoprobe GND -> Pico B GND
picoprobe GP2 -> Pico B SWCLK
picoprobe GP3 -> Pico B SWDIO
picoprobe GP4/UART1 TX -> Pico B GP1/UART0 RX
picoprobe GP5/UART1 RX -> Pico B GP0/UART0 TX
picoprobe VSYS -> Pico B VSYS
(getting-started-with-pico.pdf (2021-03-05)
Appendix A: Using Picoprobe の Picoprobe Wiring 参照)
(9).vscode/launch.jsonの修正
---
"gdbPath" : "gdb-multiarch",
"device": "RP2040",
"configFiles": [
"interface/picoprobe.cfg", <<=raspberrypi-swd.cfg をpicoprobe.cfgに変更
"target/rp2040.cfg"
],
"svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",
"runToMain": true,
---
(10)VScode でデバッグする。
$ code
VISUAL STUDIO Code画面になる
1)openフォルダで先で設定したフォルダを開く
2)ウィンドウ下のバーに「キットが選択されていません」となるのでそこをクリックし、
GCC for arm-none-eabiを選ぶ
3)ウィンドウ下のバーの「CMake:[Dbug]:準備完了」をクリック
4)ウィンドウ上にDebug選択プルダウンメニューがでるので選択
5)メニューRun -> Start Debugging[F5] 選択
6)プロジェクト選択プルダウンメニューから新しく作ったプロジェクトを選択
main()でブレークした状態となり、デバッグができる。
生成されたmain()コードなのでこれを修正して使う。
(11)自分用のCプロジェクトの自動生成とVisualStudio-Codeでデバッグ
$ cd ~/pico
$ git clone https://github.com/raspberrypi/pico-project-generator.git
$ cd ~/pico/pico-project-generator
$ ./pico_project.py --gui
[Project Name:] m_core1
[Location:] /home/pi/pico
[Library Options] なしでそのまま
[Console Options] UARTにするかUSBシリアルにするか選択
[Code Optins] なしでそのまま
[Build Options] [x]Run Build [x]Create VSCode project Debugger=picoprobe
[OK] クリック、その後「OK」クリック。
[quit] クリック。
◎コマンドラインでプロジェクトを作る場合は作成したいフォルダに cd xxxx してから、
/home/pi/pico/pico-project-generator/pico_project.py -uart --project vscode -d 1 プロジェクト名
VS-code用(--project vscode)のpicoprobe(-d 1)の設定ファイルを作る。
これでVscodeの環境とc言語 mainの雛形プログラムが作成される。
UARTのデバッグはpicoprobeのUSBケーブル経由で行う。
$ minicom -b 115200 -D /dev/ttyACM0
(12)せっかくのマルチコアチップなので体験してみる。
設定は上記のようにおこなう。
$ nano m_core1/m_core1.c
-----
#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/multicore.h"
// define LED
#define LED_B 25
static uint8_t led_b;
bool repeating_timer_callback(struct repeating_timer *t) {
gpio_put(LED_B, led_b);
led_b ^= 1;
return true;
}
// Program core1
void core1_program(void)
{
struct repeating_timer timer;
gpio_init(LED_B);
gpio_set_dir(LED_B, GPIO_OUT);
led_b = 1;
add_repeating_timer_ms(500, repeating_timer_callback, NULL, &timer);
while(1) {
asm volatile("nop");
}
}
int main() {
// Start core1
multicore_launch_core1(core1_program);
sleep_ms(5000);
while(1) {
asm volatile("nop");
}
return 0;
}
-----修正
$ nano m_core1/CMakeLists.txt
----
target_link_libraries(testm1 pico_stdlib pico_multicore)
---- "pico_multicore"を追加する
VISUAL STUDIO Code画面から上記のように修正してもよい。
メニューRun -> Start Debugging[F5] 選択
コンパイル後、実行して5秒後も同じ間隔でLEDが点滅する。
(13)RTCが結構正確に時を刻む。24時間以上で1秒位あるかどうかくらいです。
まだ先の長い話ですが、C-SDKサンプルでそのまま使うと西暦2100年はうるう年で動作します。
2100-02-28 23:59までにRTC: CTRL Register #8bit FORCE_NOTLEAPYEAR = 1 にしましょう。
2100-03-01 以降には0に。
4年毎のうるう年計算のみをする。
曜日設定があるので曜日計算を調べてみた。
昔の資料にある数式を使って現在の曜日計算すると正しくないものがある。
ユリウス日から求めるのも手かも。ユリウス日の計算方法も数種類ある。
Zellerの公式
【参考】[改訂新版]C言語による標準アルゴリズム事典 奥村晴彦 技術評論社 2018
Y 西暦4桁
M 月
D 日付
① M <= 2 のとき
M + 12 = M (1月を前年13月とする、 2月を前年14月とする)
Y - 1 = Y
② Y + INT( Y / 4 ) - INT( Y / 100 ) + INT( Y / 400 )
+ INT(( 13 * M + 8 ) / 5 ) + D = WDAY
WDAY Mod 7 = w-day
w-day 0: 日 1:月 2:火 3:水 4:木 5:金 6:土
割り算計算は小数点以下切り捨て。
【参考】教室に電卓を! (1) 一松信 海鳴社 1982
Y 西暦4桁
M 月
D 日付
有効範囲:1900.3.1~2100.2.28
① Y − 1900 = Y
M <= 2 のとき
M + 12 = M (1月を前年13月とする、 2月を前年14月とする)
Y - 1 = Y
② Y + INT( Y / 4 ) + INT(30.6 * ( M - 3) + 0.5 ) + D + 3 = WDAY
WDAY Mod 7 = w-day
w-day 0: 日 1:月 2:火 3:水 4:木 5:金 6:土
割り算計算は小数点以下切り捨て。
(14)pico-playground I2Sオーディオ出力
amazonで「HiLetgo PCM5102 ラズベリーパイpHATフォーマット用デジタルオーディオボードPCM5102
I2S IIS用ステレオDAC D/AコンバータPLLボイスモジュール」
を買って使ってみた。
参照:https://shop.pimoroni.com/products/pimoroni-pico-vga-demo-base
vscodeからそのままではコンパイルしても音はでない。pimoroniの説明にあるように
$ cd ~/pico/pico-playground
$ rm -rf build
$ mkdir build
$ cd build
$ cmake -D"PICO_BOARD=vgaboard" ..
$ cd apps
$ make
手でコンパイルすると、
apps/usb_sound_card/usb_sound_card.uf2 ができるので、PICOに書き込む。
配線:
pico B GND -> HiLetgo PCM5102 GND
pico B GP28 -> HiLetgo PCM5102 LCK
pico B GP27 -> HiLetgo PCM5102 BCK
pico B GP26 -> HiLetgo PCM5102 DIN
pico B VSYS -> HiLetgo PCM5102 VIN
_ _ _ _ _ HiLetgo PCM5102 SCK -> GND
AUDIO JACK -> ヘッドホン
これで音が出るようになる。USBケーブルで接続してSOUNDデバイスを確認する。
stdioのUARTは変更されるので、配線を変更する。
( ~/pico/pico-sdk/src/boards/include/boards/vgaboard.hより)
picoprobe GP4/UART1 TX -> Pico B GP21/UART1 RX
picoprobe GP5/UART1 RX -> Pico B GP20/UART1 TX
確認は、
$ minicom -b 115200 -D /dev/ttyACM0
VSCodeでcmakeするには、
$ cd ~/pico/pico-playground
$ mkdir .vscode
$ cp ~/pico/pico-examples/ide/vscode/launch-raspberrypi-swd.json .vscode/launch.json
$ cp ~/pico/pico-examples/ide/vscode/settings.json .vscode/settings.json
$ nano ~/pico/pico-playground/.vscode/settings.json
---
"cmake.buildBeforeRun": true,
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
"cmake.configureArgs": [ "-DPICO_BOARD=vgaboard" ], <<<===追加
"cmake.configureOnOpen": true
--- 1行追加
$ nano ~/pico/pico-playground/.vscode/launch.json
---
"gdbPath" : "gdb-multiarch",
"device": "RP2040",
"configFiles": [
"interface/picoprobe.cfg", <<=raspberrypi-swd.cfg を環境にあわせてpicoprobe.cfgに変更
"target/rp2040.cfg"
],
---
2021-01-29 「BLE HID Keyboard」
BBC Micro:bit V2でnRF52833となったのでやってみた。
Micro:bit GOを取り寄せ。
技適マークあり。
箱の中の仕切り紙の電池カバーを組み立てる。
まず、電池をつないでみる。
SPから音が出る。A → B ボタン押す。
Get startedの説明書のようにデモが始まる。
・・・・
nRF52 SDKでUARTを使う場合はBoardのヘッダーファイルの
----pca10100.h等------
#define RX_PIN_NUMBER 40 // Micro:bit-v2 USB Serial P1.08
#define TX_PIN_NUMBER 6 // Micro:bit-v2 USB Serial P0.06
を変更するとUSBケーブルをつなぎ、minicomコマンド"minicom -b 115200 -D /dev/ttyACM0"で通信可能になる。
GPIOについては、エッジコネクタP8(P0.10),P9(P0.09)がなぜか使えない。
https://makecode.microbit.org/で作ったSW入力が使えるので普通のGPIOにする手段があるのだろう。
WEB検索したが教えてくれるものが見つからない。
LSM303AGRはnRF52SDKコードで使える。
nRF52SDKの xamples/peripheral/twi_sensor/ を修正。
(1)Makefile: pcs10040/blank/armgccの 52832 ー> 52833
(2)sdk_config: pcs10040/blank/config
#define NRFX_TWI0_ENABLED 1
#define NRFX_TWI1_ENABLED 1 有機ELを使うので。
(3)main.c:
TWIのインスタンス2個にする。
TWI割り込み未使用に修正。
16x16フォント、6x8フォント定義。
外部TWI手順追加。
LSM303AGR初期化
LSM303AGR_ACC_CTRL_REG1 = 0x57 //Accel = 100Hz(Normal mode)
LSM303AGR_ACC_TEMP_CFG_REG = 0xC0 //Enable Temperetue
LSM303AGR_MAG_CFG_REG_A = 0x80 //Mag = 10Hz(high-resolution and continuous mode)
// tempereture enable
LSM303AGR_ACC_CTRL_REG4 = 0x80 //BDU on
LSM303AGR_MAG_CFG_REG_C = 0x00 //Mag data-ready interrupt disenable
LSM303AGR温度読み込み
read_sensor_data(LSM303AGR_ACC_ADDR, LSM303AGR_ACC_OUT_TEMP_L, &ldata);
read_sensor_data(LSM303AGR_ACC_ADDR, LSM303AGR_ACC_OUT_TEMP_H, &hdata);
気温 = ((int8_t)hdata) + 25;
SSD1306制御用の関数作成。
コマンド単位でひとまとめで転送
データはバイト単位でも転送可
SSD1306温度表示作成。
以上が修正の概要。
・・・・
#endif
USB接続してmicro:bitのドライブのなかにあるHTMLを開くと説明書のページが表示される。
フラッシュメモリに書き込んで最初に戻したい場合は、
左メニュー”Out of box experience”より
[Download the out of box .hex file]ボタンをクリックしてHeXファイルをダウンロードする。
これをUSB MICROBITドライブにドラッグコピーすると最初の状態になる。
・・・・
コンパイル・書き込みをRaspberry PI/ Raspberry OS (Raspbian)でする。
SDK, Softdeviceダウンロード
https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52833
タグ Download クリック
下の「Download all files as .zip」クリック
(s113_nerf52_7.2.0.zip , nRF5_SDK_17.0.2_d674dde.zip チェックされていること)
DeviceDownload.zipがダウンロードされる
でBLEのプログラムをやってみた。
各ZIPファイルを解凍する。
コンパイラーインストール。
$ sudo apt install gcc-arm-none-eabi
arm コンパイラインストール
./nRF5_SDK_17.0.2_d674dde/components/toolchain/gcc/Makefile.posix
コンパイラ情報修正
----Makefile.posix-----
GNU_INSTALL_ROOT ?= /usr/bin/ <<==修正
GNU_VERSION ?= 7.3.1
GNU_PREFIX ?= arm-none-eabi
---修正
GCCバージョンは /usr/bin/arm-none-eabi-gcc --version で調べる。
./nRF5_SDK_17.0.2_d674dde/examples/ble_peripheral/ble_app_hids_keyboard/pca10100/s113/armgcc
ble keyboardサンプルコンパイル位置
SDKサンプルのgccディレクトリでMekeできる。
ファイル./nRF5_SDK_17.0.2_d674dde/components/boards/pca10100.h修正
-----patch.1------
--- pca10100-org.h 2020-09-11 14:43:54.000000000 +0900
+++ pca10100.h 2021-01-04 13:21:38.151062040 +0900
@@ -46,49 +46,64 @@
#include "nrf_gpio.h"
-// LEDs definitions for PCA10056
-#define LEDS_NUMBER 4
+// LEDs definitions for Micro:bit V2
+#define LEDS_NUMBER 10
-#define LED_1 NRF_GPIO_PIN_MAP(0,13)
-#define LED_2 NRF_GPIO_PIN_MAP(0,14)
-#define LED_3 NRF_GPIO_PIN_MAP(0,15)
-#define LED_4 NRF_GPIO_PIN_MAP(0,16)
+#define LED_1 28 // col 1 GPIO P0.28
+#define LED_2 11 // col 2 P0.11
+#define LED_3 31 // col 3 P0.31
+#define LED_4 37 // col 4 P1.05
+#define LED_5 30 // col 5 P0.30
+#define LED_6 21 // row 1 P0.21
+#define LED_7 22 // row 2 P0.22
+#define LED_8 15 // row 3 P0.15
+#define LED_9 24 // row 4 P0.24
+#define LED_10 19 // row 5 P0.19
#define LED_START LED_1
-#define LED_STOP LED_4
+#define LED_STOP LED_10
#define LEDS_ACTIVE_STATE 0
-#define LEDS_LIST { LED_1, LED_2, LED_3, LED_4 }
+#define LEDS_LIST { LED_1, LED_2, LED_3, LED_4, LED_5, LED_6, LED_7, LED_8, LED_9, LED_10 }
#define LEDS_INV_MASK LEDS_MASK
-
-#define BSP_LED_0 13
-#define BSP_LED_1 14
-#define BSP_LED_2 15
-#define BSP_LED_3 16
-
-#define BUTTONS_NUMBER 4
-
-#define BUTTON_1 11
-#define BUTTON_2 12
-#define BUTTON_3 24
-#define BUTTON_4 25
+// -----------------------LED_1..10 same number
+#define BSP_LED_0 LED_1
+#define BSP_LED_1 LED_2
+#define BSP_LED_2 LED_3
+#define BSP_LED_3 LED_4
+#define BSP_LED_4 LED_5
+#define BSP_LED_5 LED_6
+#define BSP_LED_6 LED_7
+#define BSP_LED_7 LED_8
+#define BSP_LED_8 LED_9
+#define BSP_LED_9 LED_10
+
+#define BUTTONS_NUMBER 2
+
+#define BUTTON_1 14 // BUTTON-A
+#define BUTTON_2 23 // BUTTON-B
+//#define BUTTON_3 24
+//#define BUTTON_4 25
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
#define BUTTONS_ACTIVE_STATE 0
-#define BUTTONS_LIST { BUTTON_1, BUTTON_2, BUTTON_3, BUTTON_4 }
+#define BUTTONS_LIST { BUTTON_1, BUTTON_2 }
#define BSP_BUTTON_0 BUTTON_1
#define BSP_BUTTON_1 BUTTON_2
-#define BSP_BUTTON_2 BUTTON_3
-#define BSP_BUTTON_3 BUTTON_4
+//#define BSP_BUTTON_2 BUTTON_3
+//#define BSP_BUTTON_3 BUTTON_4
-#define RX_PIN_NUMBER 8
-#define TX_PIN_NUMBER 6
+// // Micro:bit-v2 P0, P1, P2 maybe? Let's try.
+//#define RX_PIN_NUMBER 13 // Micro:bit-v2 P15 OK
+//#define TX_PIN_NUMBER 1 // Micro:bit-v2 P14 OK
+#define RX_PIN_NUMBER 32 // Micro:bit-v2 P20
+#define TX_PIN_NUMBER 26 // Micro:bit-v2 P19
#define CTS_PIN_NUMBER 7
#define RTS_PIN_NUMBER 5
-#define HWFC true
+#define HWFC false
// serialization APPLICATION board - temp. setup for running serialized MEMU tests
#define SER_APP_RX_PIN NRF_GPIO_PIN_MAP(1,13) // UART RX pin number.
------------
$ patch pca10100.h < patch.1
ファイル./nRF5_SDK_17.0.2_d674dde/examples/ble_peripheral/ble_app_hids_keyboard/main.c修正
-----patch.2-------
--- main-org.c 2020-09-11 14:43:56.000000000 +0900
+++ main.c 2021-01-05 14:39:22.527826352 +0900
@@ -744,6 +744,7 @@
sensorsim_init(&m_battery_sim_state, &m_battery_sim_cfg);
}
+#if NRF_BLE_CONN_PARAMS_ENABLED==1
/**@brief Function for handling a Connection Parameters error.
*
@@ -776,7 +777,7 @@
err_code = ble_conn_params_init(&cp_init);
APP_ERROR_CHECK(err_code);
}
-
+#endif
/**@brief Function for starting timers.
*/
@@ -1523,6 +1524,14 @@
err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_event_handler);
APP_ERROR_CHECK(err_code);
+ //+++++++++++++++++
+ bsp_board_led_off(5);
+ bsp_board_led_on(6);
+ bsp_board_led_on(7);
+ bsp_board_led_on(8);
+ bsp_board_led_on(9);
+ //+++++++++++++++++
+
err_code = bsp_btn_ble_init(NULL, &startup_event);
APP_ERROR_CHECK(err_code);
@@ -1583,7 +1592,9 @@
advertising_init();
services_init();
sensor_simulator_init();
+#if NRF_BLE_CONN_PARAMS_ENABLED==1
conn_params_init();
+#endif
buffer_init();
peer_manager_init();
------------------
$ patch main.c < patch.2
SDKの環境を設定する。
参照:https://www.u-blox.com/sites/default/files/RC-OscillatorConfiguration_AppNote_%28UBX-20009242%29.pdf
RC発信クロック設定方法 config
nRF5_SDK_.../examples/ble_peripheral/ble_app_hids_keyboard/pca10100/s113/config/sdk_config.h
-----
(1)以下のnrfx_clockブロック
// <e> NRFX_CLOCK_ENABLED - nrfx_clock - CLOCK peripheral driver
#define NRFX_CLOCK_CONFIG_LF_SRC 0
(2)nrf_drv_clockブロック
// <e> NRF_CLOCK_ENABLED - nrf_drv_clock - CLOCK peripheral driver - legacy layer
#define CLOCK_CONFIG_LF_SRC 0
(3)SoftDevice clock configurationブロック
// <h> Clock - SoftDevice clock configuration
#define NRF_SDH_CLOCK_LF_SRC 0
#define NRF_SDH_CLOCK_LF_RC_CTIV 16
#define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 2
#define NRF_SDH_CLOCK_LF_ACCURACY 1
(4)UARTピン
#define HCI_UART_RX_PIN 32 // Micro:bit-v2 P20
#define HCI_UART_TX_PIN 26 // Micro:bit-v2 P19
pca10100.h で定義したもの
#define HCI_UART_RTS_PIN 16
#define HCI_UART_CTS_PIN 34
これは空きピンを割り当てました
#define NRF_LOG_BACKEND_UART_TX_PIN 26 // Micro:bit-v2 P19
オリジナルがUART_TXピンと同じだったので
(5)#define NRF_BLE_CONN_PARAMS_ENABLED 0 はWindows10対策
------patch.3------
--- sdk_config-org.h 2020-09-11 14:43:56.000000000 +0900
+++ sdk_config.h 2021-01-05 15:14:16.142926150 +0900
@@ -131,7 +131,7 @@
// <e> NRF_BLE_CONN_PARAMS_ENABLED - ble_conn_params - Initiating and executing a connection parameters negotiation procedure
//==========================================================
#ifndef NRF_BLE_CONN_PARAMS_ENABLED
-#define NRF_BLE_CONN_PARAMS_ENABLED 1
+#define NRF_BLE_CONN_PARAMS_ENABLED 0
#endif
// <o> NRF_BLE_CONN_PARAMS_MAX_SLAVE_LATENCY_DEVIATION - The largest acceptable deviation in slave latency.
// <i> The largest deviation (+ or -) from the requested slave latency that will not be renegotiated.
@@ -1771,7 +1771,7 @@
// <196609=> External Full Swing
#ifndef NRFX_CLOCK_CONFIG_LF_SRC
-#define NRFX_CLOCK_CONFIG_LF_SRC 1
+#define NRFX_CLOCK_CONFIG_LF_SRC 0
#endif
// <o> NRFX_CLOCK_CONFIG_IRQ_PRIORITY - Interrupt priority
@@ -4729,7 +4729,7 @@
// <196609=> External Full Swing
#ifndef CLOCK_CONFIG_LF_SRC
-#define CLOCK_CONFIG_LF_SRC 1
+#define CLOCK_CONFIG_LF_SRC 0
#endif
// <q> CLOCK_CONFIG_LF_CAL_ENABLED - Calibration enable for LF Clock Source
@@ -6731,22 +6731,22 @@
// <o> HCI_UART_RX_PIN - UART RX pin
#ifndef HCI_UART_RX_PIN
-#define HCI_UART_RX_PIN 8
+#define HCI_UART_RX_PIN 32 // Micro:bit-v2 P20
#endif
// <o> HCI_UART_TX_PIN - UART TX pin
#ifndef HCI_UART_TX_PIN
-#define HCI_UART_TX_PIN 6
+#define HCI_UART_TX_PIN 26 // Micro:bit-v2 P19
#endif
// <o> HCI_UART_RTS_PIN - UART RTS pin
#ifndef HCI_UART_RTS_PIN
-#define HCI_UART_RTS_PIN 5
+#define HCI_UART_RTS_PIN 16
#endif
// <o> HCI_UART_CTS_PIN - UART CTS pin
#ifndef HCI_UART_CTS_PIN
-#define HCI_UART_CTS_PIN 7
+#define HCI_UART_CTS_PIN 34
#endif
// </e>
@@ -7581,7 +7581,7 @@
#endif
// <o> NRF_LOG_BACKEND_UART_TX_PIN - UART TX pin
#ifndef NRF_LOG_BACKEND_UART_TX_PIN
-#define NRF_LOG_BACKEND_UART_TX_PIN 6
+#define NRF_LOG_BACKEND_UART_TX_PIN 26 // Micro:bit-v2 P19
#endif
// <o> NRF_LOG_BACKEND_UART_BAUDRATE - Default Baudrate
@@ -11789,12 +11789,12 @@
// <2=> NRF_CLOCK_LF_SRC_SYNTH
#ifndef NRF_SDH_CLOCK_LF_SRC
-#define NRF_SDH_CLOCK_LF_SRC 1
+#define NRF_SDH_CLOCK_LF_SRC 0
#endif
// <o> NRF_SDH_CLOCK_LF_RC_CTIV - SoftDevice calibration timer interval.
#ifndef NRF_SDH_CLOCK_LF_RC_CTIV
-#define NRF_SDH_CLOCK_LF_RC_CTIV 0
+#define NRF_SDH_CLOCK_LF_RC_CTIV 16
#endif
// <o> NRF_SDH_CLOCK_LF_RC_TEMP_CTIV - SoftDevice calibration timer interval under constant temperature.
@@ -11802,7 +11802,7 @@
// <i> if the temperature has not changed.
#ifndef NRF_SDH_CLOCK_LF_RC_TEMP_CTIV
-#define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 0
+#define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 2
#endif
// <o> NRF_SDH_CLOCK_LF_ACCURACY - External clock accuracy used in the LL to compute timing.
@@ -11821,7 +11821,7 @@
// <11=> NRF_CLOCK_LF_ACCURACY_1_PPM
#ifndef NRF_SDH_CLOCK_LF_ACCURACY
-#define NRF_SDH_CLOCK_LF_ACCURACY 7
+#define NRF_SDH_CLOCK_LF_ACCURACY 1
#endif
// </h>
-------------------
$ patch sdk_config.h < patch.3
$ make
$ nano cat_softdev.sh
-------------作成
#!/bin/sh
mkdir -p Micro.bit
srec_cat ../../../../../../components/softdevice/s113/hex/s113_nrf52_7.2.0_softdevice.hex -intel _build/nrf52833_xxaa.hex -intel -o _build/micro-bit.hex -intel --line-length=44
cp _build/nrf52833_xxaa.* Micro.bit
cp _build/micro-bit.hex Micro.bit
-------------
srec_catコマンドは apt install
srec_catは1行で実行
できたHEXファイルとソフトデバイスHEXと合成されたHEXファイルがいる。INTEL-HEXを結合する
$ sudo apt install srecord
$ chmod +x cat_softdev.sh
$ ./cat_softdev.sh
Micro:bitはUSBケーブルで接続するとメモリードライブとなる。
Micro.bitディレクトリにできたmicro-bit.hexをUSBメモリのMICROBITドライブにドラッグコピー。
前もってUSBシリアルケーブル接続して minicom -b 115200 -D /dev/ttyUSB0 コマンド実行するとログが表示。
プログラム起動時、5x5LEDの左上1個が点滅する。
Add-deviceリストでペアリングする。5x5LEDの左上1個が点灯する。
ただし、一度remove-deviceするとその後、リストに表示しなくなる。
RESETボタンを押しながらか、電源をONする前にボタンB(SHIFTキー)を押しながら、
RESETボタンを離すか、電源ONするとペアリングリストに表示される。
ボタンAを押すと1文字入力される。"hello"が繰り返す。ボタンBはシフトキー。
・・・・・・・・・・・・・・・
LEDブリンクをやってみる。
ファイル: ./examples/peripheral/blinky/pca10100e/blank/armgcc/Makefile
---
nrf52820 を nrf52833 に修正する
----patch.1----------
--- Makefile-old 2020-09-11 10:09:32.000000000 +0900
+++ Makefile 2021-01-04 09:27:39.237863000 +0900
@@ -1,16 +1,16 @@
PROJECT_NAME := blinky_pca10100e
-TARGETS := nrf52820_xxaa
+TARGETS := nrf52833_xxaa
OUTPUT_DIRECTORY := _build
SDK_ROOT := ../../../../../..
PROJ_DIR := ../../..
-$(OUTPUT_DIRECTORY)/nrf52820_xxaa.out: \
+$(OUTPUT_DIRECTORY)/nrf52833_xxaa.out: \
LINKER_SCRIPT := blinky_gcc_nrf52.ld
# Source files common to all targets
SRC_FILES += \
- $(SDK_ROOT)/modules/nrfx/mdk/gcc_startup_nrf52820.S \
+ $(SDK_ROOT)/modules/nrfx/mdk/gcc_startup_nrf52833.S \
$(SDK_ROOT)/components/libraries/log/src/nrf_log_frontend.c \
$(SDK_ROOT)/components/libraries/log/src/nrf_log_str_formatter.c \
$(SDK_ROOT)/components/boards/boards.c \
@@ -28,7 +28,7 @@
$(SDK_ROOT)/components/libraries/strerror/nrf_strerror.c \
$(SDK_ROOT)/modules/nrfx/soc/nrfx_atomic.c \
$(PROJ_DIR)/main.c \
- $(SDK_ROOT)/modules/nrfx/mdk/system_nrf52820.c \
+ $(SDK_ROOT)/modules/nrfx/mdk/system_nrf52833.c \
# Include folders common to all targets
INC_FOLDERS += \
@@ -70,7 +70,7 @@
CFLAGS += -DCONFIG_GPIO_AS_PINRESET
CFLAGS += -DDEVELOP_IN_NRF52833
CFLAGS += -DFLOAT_ABI_SOFT
-CFLAGS += -DNRF52820_XXAA
+CFLAGS += -DNRF52833_XXAA
CFLAGS += -DNRFX_COREDEP_DELAY_US_LOOP_CYCLES=3
CFLAGS += -mcpu=cortex-m4
CFLAGS += -mthumb -mabi=aapcs
@@ -92,7 +92,7 @@
ASMFLAGS += -DCONFIG_GPIO_AS_PINRESET
ASMFLAGS += -DDEVELOP_IN_NRF52833
ASMFLAGS += -DFLOAT_ABI_SOFT
-ASMFLAGS += -DNRF52820_XXAA
+ASMFLAGS += -DNRF52833_XXAA
ASMFLAGS += -DNRFX_COREDEP_DELAY_US_LOOP_CYCLES=3
# Linker flags
@@ -104,10 +104,10 @@
# use newlib in nano version
LDFLAGS += --specs=nano.specs
-nrf52820_xxaa: CFLAGS += -D__HEAP_SIZE=4096
-nrf52820_xxaa: CFLAGS += -D__STACK_SIZE=4096
-nrf52820_xxaa: ASMFLAGS += -D__HEAP_SIZE=4096
-nrf52820_xxaa: ASMFLAGS += -D__STACK_SIZE=4096
+nrf52833_xxaa: CFLAGS += -D__HEAP_SIZE=4096
+nrf52833_xxaa: CFLAGS += -D__STACK_SIZE=4096
+nrf52833_xxaa: ASMFLAGS += -D__HEAP_SIZE=4096
+nrf52833_xxaa: ASMFLAGS += -D__STACK_SIZE=4096
# Add standard libraries at the very end of the linker input, after all objects
# that may need symbols provided by these libraries.
@@ -117,12 +117,12 @@
.PHONY: default help
# Default target - first one defined
-default: nrf52820_xxaa
+default: nrf52833_xxaa
# Print all targets that can be built
help:
@echo following targets are available:
- @echo nrf52820_xxaa
+ @echo nrf52833_xxaa
@echo sdk_config - starting external tool for editing sdk_config.h
@echo flash - flashing binary
@@ -137,8 +137,8 @@
# Flash the program
flash: default
- @echo Flashing: $(OUTPUT_DIRECTORY)/nrf52820_xxaa.hex
- nrfjprog -f nrf52 --program $(OUTPUT_DIRECTORY)/nrf52820_xxaa.hex --sectorerase
+ @echo Flashing: $(OUTPUT_DIRECTORY)/nrf52833_xxaa.hex
+ nrfjprog -f nrf52 --program $(OUTPUT_DIRECTORY)/nrf52833_xxaa.hex --sectorerase
nrfjprog -f nrf52 --reset
erase:
---------------------
$ patch Makefile < patch.1
---修正
$ nano ./examples/peripheral/blinky/main.c
---
int main(void)
{
/* Configure board. */
bsp_board_init(BSP_INIT_LEDS);
bsp_board_led_on(5);
bsp_board_led_on(6);
bsp_board_led_on(7);
bsp_board_led_on(8);
bsp_board_led_on(9);
/* Toggle LEDs. */
while (true)
{
for (int r = 5; r < LEDS_NUMBER; r++ )
{
bsp_board_led_off(r);
for (int i = 0; i < 5; i++)
{
bsp_board_led_invert(i);
nrf_delay_ms(500);
bsp_board_led_invert(i);
nrf_delay_ms(500);
}
bsp_board_led_on(r);
}
}
}
---main()を上記のように修正
$ cd ./examples/peripheral/blinky/pca10100e/blank/armgcc
$ make
$ cd ./examples/peripheral/blinky/pca10100e/blank/armgcc/_build
Micro:bitをUSB接続する。
nrf52833_xxaa.hex をMicro:bit USBドライブにコピーする.
LED 5x5マトリックスのLED1個ずつ点灯、消灯を繰り返す。
・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
ワイヤレスキーボードを作ってみたくなり6年くらいほったらかしていたNRF51822 Blutooth基板を出してきて始めた。
同じNRF51822デバイスを使っているものは以外といっぱいある。
スイッチサイエンス HRM1017 (emded, breakout基板)
太陽誘電 Bluetooth
Braveridge BVMCN5301 (segger J-link LITE付きがある)
BBC Micro:bit
コンパイル・書き込みをRaspberry PI/ Raspberry OS (Raspbian)でする。
新しいSDKをやってみたけれども、なんともならず時間だけが費やされてしまった。
BLE開発入門 - はんだ付けからファームウェアの書き込みまで
https://qiita.com/k-yamada-github/items/27968882f7f38efda60a
を手がかりに
nrf5-SDK古いバージョン
https://developer.nordicsemi.com/nRF5_SDK/
nrf51_sdk_v6_1_0_b2ec2e6.zip
s110_nrf51822_7.3.0_softdevice
https://www.nordicsemi.com/Software-and-tools/Software/S110/Download#infotabs
s110_nrf51822_7.3.0.zip ダウンロードしたところ(s110 7.3にチェックする)
でBLEのプログラムをやってみた。
各ZIPファイルを解凍する。
コンパイラーインストール。
$ sudo apt install gcc-arm-none-eabi
arm コンパイラインストール
$ nano nRF5_SDK_xx/nrf51822/Source/templates/gcc/Makefile.posix
---
GNU_INSTALL_ROOT := /usr
GNU_VERSION := 7.3.1
GNU_PREFIX := arm-none-eabi
---修正
GCCバージョンは /usr/bin/arm-none-eabi-gcc --version で調べる。
SDKサンプルのgccディレクトリでMekeできる。
nRF5_SDK_xx/nrf51822/Source/templates/gcc/gcc_nrf51_xxx_xxx.ldがリンクアドレス設定ファイル。
Makefileの ”DEVICE_VARIANT”、"USE_SOFTDEVICE"で名前が決まる。
$ cd nRF5_SDK_xx/nrf51822/Board/nrf6310/s110/ble_app_hids_keyboard/
$ nano main.c
--
static void ble_stack_init(void)
{
uint32_t err_code;
// Initialize the SoftDevice handler module.
// SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, true);
SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION, true); <<==修正
--
32KHz内蔵RC発信CLOCKにする。
$ cd gcc
$ make clean
$ make
LED, BUTTONのポートを変更しなくてもはBLEペアリングテストはできる。
できたHEXファイルとソフトデバイスHEXと合成されたHEXファイルがいる。INTEL-HEXを結合する
$ sudo apt install srecord
$ srec_cat s110_nrf51822_7.3.0_softdevice.hex -intel ble_hids_keyboard110_s110_xxaa.hex -intel -o micro-bit.hex -intel --line-length=44
コマンド1行で。
Micro:bit, embedはUSBケーブルで接続するとメモリードライブとなるのでドラッグ&ドロップすれば良い。
他の書き込みはBraveridge BVMCN5301に付いていたsegger J-link LITEで書き込み。
書き込みツールは以下の手順で、
https://devzone.nordicsemi.com/f/nordic-q-a/49600/segger-jlink-tools-on-raspberry-pi--
Segger JLink tools on Raspberry Pi -
にあったリンク↓
https://forum.segger.com/index.php/Thread/5693-SOLVED-J-Link-Remote-Server-on-Raspberry-Pi/?s=9291616dfd89fb558f236e94b8574ba7b817ad4f
にあったリンク↓
https://www.segger.com/downloads/jlink/JLink_Linux_arm.tgz
Acceptしてダウンロード
JLink_Linux_V680b_arm.tgz を解凍し、
cd JLink_Linux_V680b_arm
README.txt にあるコマンドを実行
$ sudo cp 99-jlink.rules /etc/udev/rules.d/
$ sudo reboot
リブートする
再起動したら JLink_Linux_V680b_armディレクトリ下で
JLinkExeを実行してフラッシュに書き込む。
$ ./JLinkExe
SEGGER J-Link Commander V6.80b (Compiled Jun 5 2020 17:46:57)
DLL version V6.80b, compiled Jun 5 2020 17:46:38
Connecting to J-Link via USB...O.K.
Firmware: J-Link Lite-Cortex-M V8 compiled Sep 15 2016 12:05:01
Hardware version: V8.00
S/N: 000000000
License(s): GDB
VTref=2.995V
Type "connect" to establish a target connection, '?' for help
J-Link>connect
=========
Please specify device / core. <Default>: xxx
Type '?' for selection dialog
Device>nrf51822
=========
Please specify target interface:
J) JTAG (Default)
S) SWD
T) cJTAG
TIF>s
===
Specify target interface speed [kHz]. <Default>: 4000 kHz
Speed> <Enter>
==========
Device "NRF51822_XXAA" selected.
Connecting to target via SWD
Found SW-DP with ID 0x0BB11477
Unknown DP version. Assuming DPv0
Scanning AP map to find all available APs
AP[1]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x04770021)
Iterating through AP map to find AHB-AP to use
AP[0]: Core found
AP[0]: AHB-AP ROM base: 0xF0000000
CPUID register: 0x410CC200. Implementer code: 0x41 (ARM)
Found Cortex-M0 r0p0, Little endian.
FPUnit: 4 code (BP) slots and 0 literal slots
CoreSight components:
ROMTbl[0] @ F0000000
ROMTbl[0][0]: E00FF000, CID: B105100D, PID: 000BB471 ROM Table
ROMTbl[1] @ E00FF000
ROMTbl[1][0]: E000E000, CID: B105E00D, PID: 000BB008 SCS
ROMTbl[1][1]: E0001000, CID: B105E00D, PID: 000BB00A DWT
ROMTbl[1][2]: E0002000, CID: B105E00D, PID: 000BB00B FPB
ROMTbl[0][1]: F0002000, CID: B105900D, PID: 000BB9A3 ???
Cortex-M0 identified.
J-Link>loadfile micro-bit.hex
==========================
Downloading file [_BOARD_5103_s110_xxaa.hex]...
Comparing flash [100%] Done.
Erasing flash [100%] Done.
Programming flash [100%] Done.
J-Link: Flash download: Bank 0 @ 0x00000000: 1 range affected (47104 bytes)
J-Link: Flash download: Total: 1.755s (Prepare: 0.055s, Compare: 0.020s, Erase: 0.939s, Program & Verify: 0.731s, Restore: 0.008s)
J-Link: Flash download: Program & Verify speed: 63 KB/s
O.K.
J-Link>exit
====
....
リセット・ホルト・GO・イレースは参考文献参照。
参考:
FAQ・テクニカルガイド 「J-Link Commander」ツール - エンビテック
https://www.embitek.co.jp/technote/jlink/JLink_HowToUse_JLinkCommander.pdf
..........................................................................
NRF51-SDKのサンプルは、
--
http://blog.suga41.com/?eid=319
nRF51のサンプルソースは内部クロックに設定されている。(2016.03.10)
--
にあるように内蔵RC16MHzになっている。
.....
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1;
while ( NRF_CLOCK->EVENTS_HFCLKSTARTED == 0){
// イベント待ち
__NOP();
}
....
のようにすると、
NRF_CLOCK->HFCLKSTAT:00010000 が NRF_CLOCK->HFCLKSTAT:00010001 のように切り替わる。
また、キーSW用 KEY_PRESS_BUTTON_PIN_NOとBOND_DELETE_ALL_BUTTON_ID に割り当てたポートを抵抗でプルアップしないとCPUがSLEEP直後にWAKEUPする。
2020-07-13 「発音辞書検索」
発音辞書検索を作ろうと思ったのは
Cマガジン 1991.4月号 発音の類似による文字のマッチングアルゴリズム:Metaphone
を発見してから。
同じような発音が似ている語を検索するための発音記号生成アルゴリズムは以下の様なものがある。
American Soundex
https://en.wikipedia.org/wiki/Soundex
Metaphone
https://en.wikipedia.org/wiki/Metaphone
NYSIIS (New York State Identification and Intelligence System)
https://en.wikipedia.org/wiki/New_York_State_Identification_and_Intelligence_System
Match Rating Codex
https://en.wikipedia.org/wiki/Match_rating_approach
母音字が注目されていないのがほとんどなので同じ生成記号でも結構引っかかる。
================
参考:
https://pypi.org/project/jellyfish/
jellyfish 0.8.2
sudo apt install python3-jellyfish
python3
---
>>> import jellyfish
>>> jellyfish.metaphone('snow')
'SNW'
>>> jellyfish.soundex('snow')
'S500'
>>> jellyfish.nysiis('snow')
'SNAO'
>>> jellyfish.match_rating_codex('snow')
'SNW'
>>> jellyfish.metaphone('virus')
'FRS'
>>> jellyfish.soundex('virus')
'V620'
>>> jellyfish.match_rating_codex('virus')
'VRS'
>>> jellyfish.nysiis('virus')
'VAR'
発音記号辞書
カーネギーメロン大学のCMU発音辞書を使う。
http://www.speech.cs.cmu.edu/cgi-bin/cmudict
The CMU Pronouncing Dictionary
ホムページにある
You can also download the dict from https://github.com/Alexir/CMUdict/blob/master/cmudict-0.7b.
からダウンロードしたcmudict-0.7bを加工して使う。
35474行目 語の文字コードが崩れているので削除するか"D_J"に修正する。
DZOKHAR JH OW2 K AA1 R
D_C D IY1 S IY1
Dxxx D EY2 JH AA1 <<<=== 35474行目 語の文字コードが崩れているので削除するか"D_J"に修正する。
E IY1
E'S IY1 Z
発音記号はIPAが一般ですがフォントが特別になるのでアルファベット文字で表現できるARPABETという記号を使う。
https://ja.wikipedia.org/wiki/ARPABET
https://en.wikipedia.org/wiki/ARPABET
ARPABET
インターネットを始めた組織が考えた記号。
この辞書からSqliteデータベースを作成する。これだと語と発音記号だけのものとなる。
--- install_cmu_dict.sh -----
#!/bin/sh
rm cmu_dict.db
cat <<EOF | tee sql.txt
CREATE TABLE alphatb
( word varchar(64) not null,
arpabet varchar(256));
EOF
sed -e "/^;;.*$/d" -e "s/'/''/g" -e "s/\([^ ]*\) \(.*\)$/insert into alphatb values \( lower\(\'\1\'\) ,\'\2\'\);/" cmudict-0.7b >> sql.txt
sqlite3 cmu_dict.db < sql.txt
-------------------------------
発音が同じようなものも検索したいのでPython3でSQL文生成前に発音の類似による文字のマッチングアルゴリズムで発音記号生成をしてしまう。
$ sudo apt install sqlite3
$ sudo apt install python3-jellyfish
$ nano cmu_sqlit3.sh
---- cmu_sqlit3.sh -----
#!/bin/sh
rm -f cmu_dict.db
cat <<EOF | tee sql.txt
CREATE TABLE alphatb
( id integer not null,
word varchar(64) not null,
arpabet varchar(256),
metaphone varchar(128),
soundex varchar(128),
nysiis varchar(128),
matchracodex varchar(128) );
EOF
python3 f01.py >> sql.txt
sqlite3 cmu_dict.db < sql.txt
-------
$ chmod +x cmu_sqlit3.sh
$ nano f01.py
------- f01.py -------
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import jellyfish
import re
try:
file = open("cmudict-0.7b") # cmu 辞書オープン
lines = file.readlines() # 辞書読み込み
seqn = 0
for line in lines: # 1行毎処理
dic1 = line.rstrip('\n') # 改行コード削除
if dic1[0] == ';': # コメント読み飛ばし
continue
dictd = re.split(' ', dic1) # 単語と発音記号分離
dictw = dictd[0]
dictw = re.sub(r'^[^A-Z]+| *[ ( ][^ ( ]*[ ) ]',r'', dictw) # 単語先頭記号文字と最後の(数字)削除で発音比較アルゴリズム関数の引数作成
meta = jellyfish.metaphone(dictw) # metaphone()
meta = meta.replace('\'','\'\'') # 発音比較文字SINGLE-QUOTEを2つにエスケープ
sndx = jellyfish.soundex(dictw) # soundex()
sndx = sndx.replace('\'','\'\'') # 発音比較文字SINGLE-QUOTEを2つにエスケープ
nyss = jellyfish.nysiis(dictw) # New York State Identification and Intelligence System()
nyss = nyss.replace('\'','\'\'') # 発音比較文字SINGLE-QUOTEを2つにエスケープ
mrcd = jellyfish.match_rating_codex(dictw) # match rating approach()
mrcd = mrcd.replace('\'','\'\'') # 発音比較文字SINGLE-QUOTEを2つにエスケープ
dictx = dictd[0].replace('\'','\'\'') # 単語 文字SINGLE-QUOTEを2つにエスケープ
seqn += 1 # 単語連番
print( 'insert into alphatb values (\''+str(seqn)+'\', lower(\''+ dictx + '\'), \'' + dictd[1] +'\', \''+ meta +'\', \''+ sndx +'\', \''+ nyss +'\', \''+ mrcd +'\');')
# SQL insert文生成
except Exception as e:
print(e)
finally:
file.close() # cmu 辞書クローズ
-------
$ ./cmu_sqlit3.sh
辞書データベースができる。133852語の発音記号。
検索プログラム
QT5インストール
$ sudo apt install python3-pyqt5 qtcreator qt5-qmake qt5-default
検索画面作成
メインメニューからqtcreator起動し、画面定義を作成する。
-------- cmu_dict_win.ui -------------------
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>922</width>
<height>488</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QTableWidget" name="tableWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>100</y>
<width>881</width>
<height>348</height>
</rect>
</property>
<property name="font">
<font>
<family>Monospace</family>
</font>
</property>
<property name="toolTip">
<string notr="true"/>
</property>
<property name="statusTip">
<string notr="true"/>
</property>
<property name="whatsThis">
<string notr="true"/>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="lineWidth">
<number>999</number>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustIgnored</enum>
</property>
<property name="autoScroll">
<bool>true</bool>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerItem</enum>
</property>
<property name="showGrid">
<bool>true</bool>
</property>
<property name="gridStyle">
<enum>Qt::DotLine</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="cornerButtonEnabled">
<bool>true</bool>
</property>
<property name="rowCount">
<number>10</number>
</property>
<property name="columnCount">
<number>4</number>
</property>
<attribute name="horizontalHeaderVisible">
<bool>true</bool>
</attribute>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>14</number>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<row/>
<row/>
<row/>
<row/>
<row/>
<row/>
<row/>
<row/>
<row/>
<row/>
<column/>
<column/>
<column/>
<column/>
<item row="0" column="0">
<property name="text">
<string/>
</property>
</item>
<item row="0" column="1">
<property name="text">
<string/>
</property>
</item>
</widget>
<widget class="QLineEdit" name="lineEWord">
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<width>591</width>
<height>32</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>30</x>
<y>0</y>
<width>68</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>単語</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>630</x>
<y>0</y>
<width>281</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>検索方法(マッチ、先頭、後方、部分)</string>
</property>
</widget>
<widget class="QPushButton" name="btnMatch">
<property name="geometry">
<rect>
<x>630</x>
<y>30</y>
<width>61</width>
<height>30</height>
</rect>
</property>
<property name="text">
<string>■■■</string>
</property>
</widget>
<widget class="QPushButton" name="btnHead">
<property name="geometry">
<rect>
<x>700</x>
<y>30</y>
<width>61</width>
<height>30</height>
</rect>
</property>
<property name="text">
<string>■■?</string>
</property>
</widget>
<widget class="QPushButton" name="btnTail">
<property name="geometry">
<rect>
<x>770</x>
<y>30</y>
<width>61</width>
<height>30</height>
</rect>
</property>
<property name="text">
<string>?■■</string>
</property>
</widget>
<widget class="QPushButton" name="btnMiddle">
<property name="geometry">
<rect>
<x>840</x>
<y>30</y>
<width>61</width>
<height>30</height>
</rect>
</property>
<property name="text">
<string>?■?</string>
</property>
</widget>
<widget class="QRadioButton" name="razBmeta">
<property name="geometry">
<rect>
<x>400</x>
<y>70</y>
<width>119</width>
<height>27</height>
</rect>
</property>
<property name="text">
<string>&metaphone</string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
<widget class="QRadioButton" name="razBsndx">
<property name="geometry">
<rect>
<x>520</x>
<y>70</y>
<width>101</width>
<height>27</height>
</rect>
</property>
<property name="text">
<string>s&oundex</string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
<widget class="QRadioButton" name="razBnyss">
<property name="geometry">
<rect>
<x>620</x>
<y>70</y>
<width>81</width>
<height>27</height>
</rect>
</property>
<property name="text">
<string>&NYSIIS</string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
<widget class="QRadioButton" name="razBmrap">
<property name="geometry">
<rect>
<x>710</x>
<y>70</y>
<width>191</width>
<height>27</height>
</rect>
</property>
<property name="text">
<string>Mat&ch rating approach </string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>220</x>
<y>70</y>
<width>171</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>発音比較アルゴリズム:</string>
</property>
</widget>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
<buttongroups>
<buttongroup name="buttonGroup"/>
</buttongroups>
</ui>
--------
検索プログラム
$ nano py.py
----------- py.py -----
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from PyQt5 import uic
import PyQt5.QtCore as QtCore
from PyQt5.QtWidgets import QTableWidget, QRadioButton, QWidget, QSizePolicy, QHeaderView, QMainWindow, QMessageBox, QApplication, QTableWidgetItem
from PyQt5.QtGui import QIcon
from PyQt5 import QtGui, QtWidgets
from subprocess import run, PIPE, Popen
import signal
import time
import sys
import os
import sqlite3
import re
# データベースファイルのパス
dbpath = 'cmu_dict.db'
class GUICmudict(QMainWindow):
def __init__(self):
"""UIファイルロード、イベントの関連付け、ウィンドウの設定"""
super().__init__()
self.currnt_dir = os.path.dirname(os.path.abspath(__file__))
self.ui = uic.loadUi(self.currnt_dir + '/cmu_dict_win.ui')
self.ui.setWindowIcon(QIcon(self.currnt_dir+'/Dict.png'))
self.ui.setWindowTitle("英語発音辞書検索")
self.ui.btnMatch.clicked.connect(self.sqlMatch)
self.ui.btnHead.clicked.connect(self.sqlHead)
self.ui.btnTail.clicked.connect(self.sqlTail)
self.ui.btnMiddle.clicked.connect(self.sqlMiddle)
self.ui.razBmeta.setChecked(True)
self.ui.tableWidget.setAlternatingRowColors(False); # 1 行おきに色を変える
app.aboutToQuit.connect(self.closeEvent) # From http://stackoverflow.com/questions/24532043/proper-way-to-handle-the-close-button-in-a-main-window-pyqt-red-x
self.ui.tableWidget.setHorizontalHeaderLabels(["","■","","[ARPABET発音記号]"])
self.ui.tableWidget.horizontalHeader().setStyleSheet("color:Blue;")
self.ui.tableWidget.horizontalHeader().setDefaultAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.ui.tableWidget.horizontalHeader().setSectionResizeMode(3, QHeaderView.Stretch)
self.ui.tableWidget.resizeColumnsToContents();
def normalWin(self):
"""通常表示"""
self.ui.show()
def FullScreen(self):
"""フルスクリーン表示"""
self.ui.showFullScreen()
def minimized_win(self):
"""ウィンドウをアイコンにする"""
self.ui.showMinimized()
def closeEvent(self):
"""システムメニュー[X]がクリックされた"""
self.ui.close()
sys.exit(0)
def sqlMatch(self):
self.ui.tableWidget.setHorizontalHeaderLabels(["","■","","[ARPABET発音記号]"])
self.ui.tableWidget.setRowCount(0)
txtword = self.ui.lineEWord.text()
self.sqlExec(txtword, 0)
def sqlHead(self):
self.ui.tableWidget.setHorizontalHeaderLabels(["■","","","[ARPABET発音記号]"])
self.ui.tableWidget.setRowCount(0)
txtword = self.ui.lineEWord.text()
self.sqlExec(txtword, 1)
def sqlTail(self):
self.ui.tableWidget.setHorizontalHeaderLabels(["","","■","[ARPABET発音記号]"])
self.ui.tableWidget.setRowCount(0)
txtword = self.ui.lineEWord.text()
self.sqlExec(txtword, 2)
#self.ui.tableWidget.setSizeAdjustPolicy(QTableWidget.QAbstractScrollArea.AdjustToContents)
#self.ui.tableWidget.resizeColumnsToContents();
def sqlMiddle(self):
self.ui.tableWidget.setHorizontalHeaderLabels(["","■","","[ARPABET発音記号]"])
self.ui.tableWidget.setRowCount(0)
txtword = self.ui.lineEWord.text()
self.sqlExec(txtword, 3)
def printWord(self, row, str_word, sqlf):
numRows = self.ui.tableWidget.rowCount()
self.ui.tableWidget.insertRow(numRows)
#Add text to the row
str_word = str_word.lower()
if sqlf == 999:
item = QTableWidgetItem(row[0])
item.setBackground(QtGui.QColor(200, 255, 200))
item.setTextAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.ui.tableWidget.setItem(numRows, 1, item)
if sqlf == 0:
item = QTableWidgetItem(str_word)
item.setBackground(QtGui.QColor(128, 240, 240))
item.setTextAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.ui.tableWidget.setItem(numRows, 1, item)
if sqlf == 1:
item = QTableWidgetItem(str_word)
item.setTextAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
item.setBackground(QtGui.QColor(128, 240, 240))
self.ui.tableWidget.setItem(numRows, 0, item)
item = QTableWidgetItem(row[0][len(str_word):])
self.ui.tableWidget.setItem(numRows, 1, item)
if sqlf == 2:
item = QTableWidgetItem(row[0][:-len(str_word)])
item.setTextAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.ui.tableWidget.setItem(numRows, 1, item)
item = QTableWidgetItem(str_word)
item.setTextAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
item.setBackground(QtGui.QColor(128, 240, 240))
self.ui.tableWidget.setItem(numRows, 2, item)
if sqlf == 3:
m = re.search(str_word, row[0])
item = QTableWidgetItem(row[0][:m.start()])
item.setTextAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.ui.tableWidget.setItem(numRows, 0, item)
item = QTableWidgetItem(str_word)
item.setTextAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
item.setBackground(QtGui.QColor(128, 240, 240))
self.ui.tableWidget.setItem(numRows, 1, item)
item = QTableWidgetItem(row[0][m.end():])
item.setTextAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.ui.tableWidget.setItem(numRows, 2, item)
item = QTableWidgetItem(row[1])
item.setTextAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
if sqlf == 999:
item.setBackground(QtGui.QColor(240, 255, 240))
else:
item.setBackground(QtGui.QColor(240, 240, 255))
self.ui.tableWidget.setItem(numRows, 3, item)
def getBtnX(self):
if self.ui.razBsndx.isChecked():
return 1
elif self.ui.razBnyss.isChecked():
return 2
elif self.ui.razBmrap.isChecked():
return 3
else:
return 0
def sqlExec(self, str_word, sqlf):
# データベース接続とカーソル生成
if len(str_word) == 0:
numRows = self.ui.tableWidget.rowCount()
self.ui.tableWidget.insertRow(numRows)
item = QTableWidgetItem("")
item.setBackground(QtGui.QColor(255, 255, 255))
self.ui.tableWidget.setItem(numRows, 0, item)
item = QTableWidgetItem("Word入力なし")
item.setBackground(QtGui.QColor(255, 255, 80))
item.setTextAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.ui.tableWidget.setItem(numRows, 1, item)
item = QTableWidgetItem("")
item.setBackground(QtGui.QColor(255, 255, 255))
self.ui.tableWidget.setItem(numRows, 2, item)
else:
connection = sqlite3.connect(dbpath)
# connection.isolation_level = None
cursor = connection.cursor()
p1_word = str_word
if sqlf == 2:
p1_word = '%' + str_word
if sqlf == 1:
p1_word = str_word + '%'
if sqlf == 3:
p1_word = '%' + str_word + '%'
cursor.execute('SELECT word, arpabet, metaphone, soundex, nysiis, matchracodex, id FROM alphatb WHERE word like lower(?) ORDER BY word', (p1_word,))
wsel = 0
for row in cursor.fetchall():
self.printWord(row, str_word, sqlf)
wsel += 1
if sqlf == 0 and wsel == 1:
btnx = self.getBtnX()
selDBid = ['metaphone', 'soundex', 'nysiis', 'matchracodex'][btnx]
selw = row[2+btnx]
idw = row[6]
numRows = self.ui.tableWidget.rowCount()
self.ui.tableWidget.insertRow(numRows)
item = QTableWidgetItem("★発音類似語★")
self.ui.tableWidget.setItem(numRows, 3, item)
cursor.execute('SELECT word, arpabet, metaphone, soundex, nysiis, matchracodex, id FROM alphatb WHERE id!=? and '+selDBid+'=? ORDER BY word', (idw,selw,))
for row in cursor.fetchall():
self.printWord(row, str_word, 999)
connection.close()
self.ui.tableWidget.resizeColumnsToContents();
self.ui.tableWidget.horizontalHeader().setSectionResizeMode(3, QHeaderView.Stretch)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = GUICmudict()
#win.FullScreen()
win.normalWin()
sys.exit(app.exec_())
-----------------------
使い方
ディレクトリ構成
.
├── Dict.png ...アイコンは名前はこれで、イメージは好みで用意すること。
├── cmu_dict.db
├── cmu_dict_win.ui
└── py.py
$ python3 py.py
単語を入力域に入力し、検索ボタンをクリック。
ボタン”■■■”
語ひとつ一致結果と似たような発音の語一覧が表示される。
アルゴリズムはいづれか一つ選択する。
ボタン”■■?”
語の先頭部分一致一覧が表示される。
似たような発音の語は出ない。
ボタン”?■■”
語の後方部分一致一覧が表示される。
似たような発音の語は出ない。
ボタン”?■?”
語の中間部分一致一覧が表示される。
似たような発音の語は出ない。
タイトルバー[X]
プログラム終了。
-------- プログラムライセンス Copylight (c) k.Shimomura. The MIT License (MIT) ---------