あらきけいすけのメモ帳

あらきけいすけの雑記帳2

高校の教科書・参考書に書かれていない指数関数の応用の基本

書きかけ
なぜこれが高校の数学、理科の学習指導要領外(要確認)なのか分からない

指数関数の応用では、指数(exponent)、基数(base, 底(てい))には無次元の量を代入し、単位を持つ量は指数関数の係数にする。
\overbrace{\mbox{(現在値)}}^{単位を持つ量}
=\overbrace{\mbox{(初期値)}}^{単位を持つ量}\times
\hspace{-12pt}{\underbrace{\mbox{(基数)}}_{基数は次元の無い量}\hspace{-12pt}
}^{\overbrace{\tiny\mbox{(現在の量)$\div$(基準となる量)}}^{指数は次元の無い量}}
例題1:複利式で預けた預金の残高
(預金残高〔円〕)
=(預入額〔円〕)\times{
\Big(\hspace{-1pt}{\underbrace{1}_{元本部分}}\hspace{-1pt}+年利率\Big)\hspace{9pt}
}^{\overbrace{\tiny\mbox{(経過時間〔年〕)$\div$(1年)}}^{単位を揃える}}
例題2:放射性物質半減期
(現在量〔\rm kg〕)
=(初期量〔kg〕)\times{
\hspace{-8pt}\underbrace{\Big(\displaystyle\frac{1}{2}\Big)}_{半減期の基数}\hspace{-8pt}
}^{\overbrace{\tiny\mbox{(経過時間〔年〕)$\div$(半減期〔年〕)}}^{単位を揃える}}

openpyxl覚え

Workbookの新規作成、データ入力、保存

import openpyxl
workbook = openpyxl.Workbook() # 新規作成
worksheet = workbook.active # ワークシートの選択
worksheet.cell(1,1).value ='test' # データ入力 cell(行,列) 添字1から
worksheet['B2'].value ='data' # データ入力
workbook.save('./test.xlsx') # ブックの保存
workbook.close() # ブックを閉じる

既存のWorkbookを開く

keep_vba, data_only, ...
openpyxl.reader.excel module — openpyxl 3.0.9 documentation

import openpyxl
wb = openpyxl.load_workbook('./test.xlsm', data_only=True, keep_vba=True)

SUPPORTED_FORMATS = ('.xlsx', '.xlsm', '.xltx', '.xltm')*1

セルデータの読み込み

iter_rows, min_row, ...
openpyxl.worksheet.worksheet module — openpyxl 3.0.9 documentation
col_idx, column_letter, ...
openpyxl.cell.cell module — openpyxl 3.0.9 documentation

import openpyxl
wb = openpyxl.load_workbook('./test.xlsm', data_only=True, keep_vba=True)
ws = wb.active

# 全部のセルを走るループ
for row in ws: # row は cell オブジェクトの tuple
  for cell in row: 
    #行番号,列番号,列文字,データ(値,式)
    print(cell.row,cell.col_idx,cell.column_letter,cell.value)

# 全部のセルを走るループ2
for iRow in range(1,ws.max_row + 1) :
  for iCol in range(0,ws.max_column) :
    print(iRow,iCol,ws[iRow][iCol].value)

# 特定の列を読む
for row in ws.iter_rows(min_row=2): # 2行目以降のA列を読むコード
  a = row[0].value # tuple なので添え字は int
  b = row[ openpyxl.utils.column_index_from_string('A') - 1 ].value
  print(a,b)

テキストの折り返し

python - Apply 'wrap_text' to all cells using openpyxl - Stack Overflow

import copy
import openpyxl
wb = openpyxl.Workbook()
ws = wb.active

cell = ws.cell(1,1)
algn = copy.copy(cell.alignment)
algn.wrapText = True
cell.alignment = algn
cell.value='all very long sentences should be wrapped.'

wb.save('./test.xlsx')

ws.cell(1,1).alignment.wrapText = True と書くと次のエラーを吐く:AttributeError: Style objects are immutable and cannot be changed.Reassign the style with a copy

ws['A1'].alignment = openpyxl.styles.Alignment(wrapText=True)

という書き方もある

セルのサイズの指定

ws.column_dimensions['A'].width = 80
ws.row_dimensions[1].height=90

wrapTextで自動で縦に広がったセルには「高さの情報」は付与されないようだ[2022.5.2]

行列のn乗を固有値だけから求める(固有ベクトルも対角行列も求めないシルベスターの公式)

\newcommand{\SD}{{\small\displaystyle}}\newcommand{\a}{\alpha}\newcommand{\b}{\beta}\newcommand{\g}{\gamma}授業のための覚書*1。 Cayley-Hamiltonの定理*2, 剰余の定理*3, Lagrange の補間*4を用いると、対角化の操作*5をスルーして行列のn乗を求めることができるのでメモ*6。シルベスターの公式*7の応用例(\small f(A):=A^n)になっている。行列のn乗なんて、ケーリー・ハミルトンの定理の式で与えらえる行列の多項式の剰余類への還元だから、多項式の剰余の定理を使えば十分。例題は3\times3行列:\SD x^n=(x^3+ax^2+bx+c)Q(x)+px^2+qx+r より \SD x^3+ax^2+bx+c=0 の解を \a, \b, \g とすると*8\SD \a^n=p\a^2+q\a+r (\b, \gも同様)である。これは3点 \SD(\a,\a^n), \SD(\b,\b^n), \SD(\g,\g^n)を通る2次関数を求めることに他ならないから、ラグランジュ補間の公式より
 \displaystyle px^2+qx+r\displaystyle =\a^n\frac{(x-\b)(x-\g)}{(\a-\b)(\a-\g)}\displaystyle +\b^n\frac{(x-\g)(x-\a)}{(\b-\g)(\b-\a)}\displaystyle +\g^n\frac{(x-\a)(x-\b)}{(\g-\a)(\g-\b)}.
よって3\times3行列 \displaystyle A固有値 \a, \b, \g が非零で縮退がないならば

行列のn乗:
\displaystyle A^n\displaystyle =\a^n\frac{(A-\b I)(A-\g I)}{(\a-\b)(\a-\g)}\displaystyle +\b^n\frac{(A-\g I)(A-\a I)}{(\b-\g)(\b-\a)}\displaystyle +\g^n\frac{(A-\a I)(A-\b I)}{(\g-\a)(\g-\b)}.
公式の意味はケイリー・ハミルトンの定理より固有値に属する固有ベクトルの空間への射影をとる行列(Frobenius covariant, フロベニウス共変行列*9)を構成できるということ*10。だからこんな応用もある;
逆行列(n=-1):
\displaystyle A^{-1}\displaystyle =\frac{1}{\a}\frac{(A-\b I)(A-\g I)}{(\a-\b)(\a-\g)}\displaystyle +\frac{1}{\b}\frac{(A-\g I)(A-\a I)}{(\b-\g)(\b-\a)}\displaystyle +\frac{1}{\g}\frac{(A-\a I)(A-\b I)}{(\g-\a)(\g-\b)}.
任意のベクトルの固有ベクトルへの分解(n=0):
\displaystyle\vec p\displaystyle =\frac{(A-\b I)(A-\g I)}{(\a-\b)(\a-\g)}\vec p\displaystyle +\frac{(A-\g I)(A-\a I)}{(\b-\g)(\b-\a)}\vec p\displaystyle +\frac{(A-\a I)(A-\b I)}{(\g-\a)(\g-\b)}\vec p.
式の形はきれいだけど、一般の場合に計算のコストが高そう。この式のありがたみの極大値は「整数成分の3\times3行列の筆算」くらいかも。

*1:筆算での処理を念頭に置いている。数式処理ソフトで瞬殺という意見はいまは無しの方向で。

*2:ケイリー・ハミルトンの定理 - Wikipedia

*3:剰余の定理 - Google 検索

*4:ラグランジュ補間 - Wikipedia

*5:3\times3行列Aの場合だと、固有値 \a, \b, \g を求め、

  1. 固有ベクトル \vec p_\a, \vec p_\b, \vec p_\g を3つとも求め、
  2. 変換行列 P=(\vec p_\a, \vec p_\b, \vec p_\g) を構成し、
  3. その逆行列 \small P^{-1} を計算し、
  4. 対角行列 \small\tilde A=P^{-1}AP=diag(\a,\b,\g) を求め、
  5. \small A^n=(P\tilde AP^{-1})^n=P\tilde A{}^nP^{-1}=P\,diag(\a^n,\b^n,\g^n)P^{-1}を求める

*6:ケーリーハミルトン n乗 - Google 検索 剰余類を用いた解法、漸化式と関連付けた解法は、高校数学に行列があった頃のページがいくつか残っているようだ。

*7:Sylvester's formula - Wikipedia このページには固有値が縮退をしている一般の場合の公式も記述されている。

*8:ここでは重解を持たないと前提する。

*9:Frobenius covariant - Wikipedia

*10:(A-\a I)(A-\b I)(A-\g I)=O より A(A-\b I)(A-\g I)=\a(A-\b I)(A-\g I). この両辺に任意のベクトル \vec p をかけて A\underbrace{(A-\b I)(A-\g I)\vec p}_{\vec q}=\a\underbrace{(A-\b I)(A-\g I)\vec p}_{\vec q} より \vec q=(A-\b I)(A-\g I)\vec p\small A固有値\a固有ベクトル

ソフトウェアへの恐怖心

慣れないシステム、慣れないソフトウェアをいじると、どの程度の「失敗」がどの程度まで「取返しがつく」のか分からないので、対象の影響範囲の大きさが想像される(あるいは想像がつかない)と、相当にビビる。「失敗へのトレランスが大きいと事前にわかること」がキーではないか?
[2020.9.19] 一晩おいて読み返すと「心理的安全性」*1そのものだと気付く。

Python 覚え

ドキュメント:https://docs.python.org/3/index.html

openpyxl を用いて結合セルの結合を解除し、データを各セルにばらまく

かなり苦労したのでメモ*1。このPythonコードの実行速度は下のVBAコードより圧倒的に速い。

#-*- coding: shift_jis -*-
import openpyxl

#元データのシート
wb = openpyxl.load_workbook('testIn.xlsx',data_only=True)
ws = wb['Sheet1']

#結合したセルの Range データを文字情報化して、バッファする
listMerged=[]
for rng in ws.merged_cells:
  listMerged.append(str(rng))

#セルの結合を解除し、左上の値を代入する
for strRng in listMerged:
  leftTop = (strRng.split(':'))[0]
  ws.unmerge_cells(strRng)
  for row in ws[strRng]:
    for cell in row:
      cell.value = ws[leftTop].value

#結果を保存する
wb.save(filename='testOut.xlsx')

ほぼ同じ動作の Excel VBA マクロ

Sub cellUnmergeDataSpread(r As Range)
    '
    ' 入力の r で決まる Range 内の結合セルデータを調べて、
    ' セルの結合を全部解除して、結合してた全てのセルにデータをばらまく
    '
    Dim o As Object, r0 As Range, v, i, j

    '[セル番号=>データの入ったセルのセル番号]の辞書の作成
    Set o = CreateObject("Scripting.Dictionary")
    For i = 1 To r.Rows.Count
        For j = 1 To r.Columns.Count
            Set r0 = r.Cells(i, j)
            v = r0.MergeArea.item(1).Address(0, 0)
            o.Add r0.Address, v
        Next j
    Next i
    r.unmerge '結合解除はここ

    For Each v In o '結合解除したセルに左上セルのデータのコピー
        r.Parent.Range(v).Value = r.Parent.Range(o.item(v)).Value
    Next v
End Sub

mergeする方は結合セルの探索にopenpyxl.worksheet.cell_range.CellRange*2を使うといいのかな?

GCC Developer Lite (GDL)を64bitのWindows 10にインストールし hello world プログラムを作成する

GCC Developer Lite (GDL) を使って自分のPCで hello world プログラムと、マイコン(ここではH8-3664F)用プログラムをC言語で作成できるようになるまでの覚書。

2022.3.1に GDL 2.7 がリリースされて、インストールの方法が大きく変わっている。本稿は GDL 2.5 の時点のもの。

GCC Developer Lite のインストール

  1. まずBesttechnology社のサイト https://www.besttechnology.co.jp/modules/knowledge/?GCC%20Developer%20Lite からインストーラ (2020.7.1現在 GDLFull2.5.1.0.exe)をダウンロードして実行する。
  2. まずインストールする言語の選択。日本語で[OK]をクリック
  3. インストーラが起動するので[次へ(N)]をクリック
  4. [使用許諾契約書の同意]が現れるので[同意する(A)]を選択して[次へ(N)]をクリック
  5. [情報]が現れるので[次へ(N)]をクリック
  6. [インストール先の指定]が現れるので、ここは C:\Program Files (x86)\BestTech のままで、[次へ(N)]をクリック
  7. [コンポーネントの選択]が現れる。*1
    1. [H8-3664Fでのみ使用]を選択するとマイコンH8-3664のプログラミングに必要なコンポーネントだけにチェックが入る。(後でWindows用を追加することも可能)FLASH WRITER, H8GCC などにチェックが入る
    2. 下から3個目の[Windows(x64)でのみ使用]*2を選択するとWindowsプログラミングに必要なコンポーネントだけにチェックが入る。(後でH8-3664用を追加することも可能)
    3. たとえば[H8-3664Fでのみ使用]の後で[Windows(x64)でのみ使用]をインストールすると[既存のコンポーネント]が現れるので[はい(Y)]をクリック
  8. [プログラムグループの指定]が現れるので[次へ(N)]をクリック
  9. [追加タスクの選択]が現れるので[次へ(N)]をクリック
  10. [インストール準備完了]が現れるので[インストール(I)]をクリック

    すると[インストール状況]の画面が現れる
  11. [GCC Developer Lite セットアップウィザードの完了]が現れるので[完了(F)]をクリック

以上でGDLのインストールは終了。H8-3664FとWindows(x64)の両方をインストールする場合には、この作業を2回行う(このとき先にインストールされたものが消されることはない)。

C言語プログラミングとプログラムの実行

注意:ここの説明は Windows(x64) がインストールしてあるものとして書かれている。

  1. デスクトップ上の[GCC Developer Lite]のアイコンをクリックしGDLを起動する

    GDLが起動する
  2. hello world 用の設定:コンソールプログラム(コマンドプロンプト上で動作するプログラム)作成用の設定
    1. [ツール(T)]→[コンパイルオプション(O)...]を選択
    2. [設定リスト]から[x64 (Console)]を選択
    3. [外部ツール連動]タブを開いて[コンパイル時に外部ツールを起動(D]のチェックボックスをオン、[外部ツール(P)]ボックスに C:\Windows\System32\cmd.exe を書き込み、[OK]をクリック
  3. hello world プログラムの作成
    GDLの青い部分に次のプログラム(ソースコード)を書くコピペする*3
#include <stdio.h>
int main (void) {
  printf("hello, world!");
  return 0;
}


  1. プログラム(ソースコード)を保存する。今回はデスクトップに"C"というフォルダを作成する。

    1. [ファイル(F)]→[名前を付けて保存(A)...]
    2. [保存するソースファイル名の指定]の左側の[デスクトップ]をクリックする

      デスクトップのフォルダが表示される。
    3. [保存するソースファイル名の指定]の右上の[新しいフォルダーの作成](下図の右上の赤枠の中のアイコン)をクリック

      [新しいフォルダー]が作成される
    4. フォルダー名を"C"に書き換える。

      そのあと"C"フォルダーをクリックする。
    5. "hello.c"という名前で保存する:図の赤枠の部分に"hello.c"と書いて[保存(s)]をクリック。

  2. プログラム(ソースコード)をビルドして、プログラム(実行ファイル)を作成する

    1. [コンパイル(C)]→[ビルド(B) F9]をクリックする。
    2. プログラムが正しいならば、[コンパイラ動作ログ](青い部分の下の空欄)に「コンパイル<成功>」が表示される

  3. プログラム(実行ファイル)を実行する

    1. コンパイルに成功したら、[INFORMATION]が現れるので[OK]をクリック
    2. コマンドプロンプトが現れるので、"hello.exe"と入力して[enter]キーを押すと、"hello, world!"と表示される。


*1:PCに余裕があれば[フルインストール]の選択もあり。

*2:[x86]は32bitのプログラム, x64は64bitのプログラムを作成する:32bit 64bit プログラミング 違い - Google 検索

*3:プログラミングの最初歩の勉強では、ミスタイプによるエラーがよく生じるので、

  1. コードをコピペして、きちんと動作することを確認する
  2. その動作するコードを1行だけ書き換え、文法エラーが無いことを確認する
  3. この作業を繰り返して、目標のソースコードに近づける
というステップを踏むのが確実なんじゃないかな。