「技術」カテゴリーアーカイブ

【数学】【PYTHON】行列のかけ算を行う

【数学】【PYTHON】行列の足し算・引き算を行う | 自分、ぼっちですが何か? (taki-lab.site)

行列のかけ算もnumpyのmatrix()を使えば簡単にできます。

実数倍のかけ算

>>> import numpy as np
>>> A = np.matrix([[80, 140], [30, 25]])
>>> 0.8 * A
matrix([[ 64., 112.],
        [ 24.,  20.]])

これは単純に各要素を実数倍する計算結果。

行列同士のかけ算

>>> A = np.matrix([[1, 3], [2, 1]])
>>> B = np.matrix([[150, 250], [130, 230]])
>>> A * B
matrix([[540, 940],
        [430, 730]])

行列同士のかけ算は、特殊な(めんどくさい)計算が必要になるのですが、

numpyを使えば簡単に計算してくれます。

Docker Composeを使用する

DOCKERでCMDコマンドを仕込んでみる。 | 自分、ぼっちですが何か? (taki-lab.site)

Dockerは1アプリケーション1コンテナというのが基本的な使い方らしいです。

今回はPHP+DBという構成を構築してみたいと思います。

こういった複数をアプリ(コンテナ)をセットで扱いたい場合は、docker-composeを使用します。

プロジェクト構成

PHPはDockerファイルで、DBはDockerHubで用意されている物を使用します。

Dockerfile

FROM php:7.4-apache

RUN apt-get update && apt-get install -y \
    tzdata \
    libpq-dev \
    && rm -rf /var/lib/apt/lists/* \
    && docker-php-ext-install pdo_pgsql

ENV TZ=Asia/Tokyo

php.ini

[Date]
date.timezone = Asia/Tokyo

[mbstring]
mbstring.language = Japanese

sample1.php

<?php
print('ただいまの日時は、'.date("Y-m-d H:i:s").'です。<br>');

$dbname='postgres';
$host='ex11_db';
$dbuser='postgres';
$dbpass='postgres';

try {
    $dbh = new PDO("pgsql:dbname=$dbname;host=$host", $dbuser, $dbpass);
    print('正常に接続されました。<br>');

    print('sysid, ユーザー名<br>');

    $sql = 'SELECT * FROM pg_user';
    foreach ($dbh->query($sql) as $row) {
        print($row['usesysid'].', ');
        print($row['usename'].'<br>');
    }
} catch (PDOException $e) {
    print('エラー:'.$e->gwtMessage());
    exit();
}

?>

docker-compose.yml

version: '3.8'

services:
  db:
    image: postgres:13.1-alpine
    container_name: 'ex11_db'
    expose:
      - "5432"
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - HOGE=hoge

  web:
    image: ex11/web:1.0
    build: ./web
    container_name: 'ex11_web'
    ports:
      - 8080:80
    working_dir: '/var/www/html'
    volumes:
      - ./web/php.ini:/usr/local/etc/php/php.ini
      - type: bind
        source: ./web/src
        target: /var/www/html
    depends_on:
      - db
~/dockerenv/ex11$ docker-compose up
~/dockerenv/ex11$ docker-compose down --rmi all

【数学】【PYTHON】行列の足し算・引き算を行う

【数学】【PYTHON】法線ベクトル(ベクトルの外積)を求める | 自分、ぼっちですが何か? (taki-lab.site)

NumPyのmatrix()を使用すれば、行列も簡単に扱うことができるようになります。

たとえば、こんな行列の計算を行う場合、

>>> import numpy as np
>>> A = np.matrix([[50, 40],[10, 10]])
>>> B = np.matrix([[30, 100],[20, 15]])
>>> A+B
matrix([[ 80, 140],
        [ 30,  25]])

DOCKERでRUNコマンドを仕込んでみる。

Dockerでコンテナ作成の勉強をする。 | 自分、ぼっちですが何か? (taki-lab.site)

DockerでRUNコマンドを使用し、パッケージをインストールするパターンです。

ファイル構成はこんな感じ。

Dockerfileの内容。

FROM php:7.4-apache

RUN apt-get update && apt-get install -y \
    tzdata \
    && rm -rf /var/lib/apt/lists/*

ENV TZ=Asia/Tokyo

WORKDIR /usr/local/etc/php

COPY php.ini ${PWD}

ARG wdir

WORKDIR $wdir

RUNで&&で区切ることによって、Buildの速度を上げるための施策らしい。

そして、最後のrmコマンドはapt-getコマンドのキャッシュを削除することによって、イメージサイズを小さくしているらしい。

これはお決まりのパターンってことだね。

php.ini

[Date]
date.timezone = Asia/Tokyo

[mbstring]
mbstring.language = Japanese

phpinfo.php

<h1>ようこそ! PHP!</h1>
ただいまの日時は、<?php echo date("Y-m-d H:i:s") ?> です。

<?php
echo phpinfo()
?>

イメージのビルド

~/dockerenv/ex02$ docker image build --build-arg wdir=/var/www/html -t ex02/php:1.0 .

イメージの実行

~/dockerenv/ex02$ docker container run --name ex02_php -d --rm -p 8080:80 --mount type=bind,src=$(pwd)/src,dst=/var/www/html ex02/php:1.0

Dockerでコンテナ作成の勉強をする。

これまで一生懸命Dockerを避けてきたのですが、

どうもすでにDockerでサービスを運用することがトレンドになっているらしいので、

これはもうやらざるを得ないかと。

そもそも前のプロジェクトでは、AWSのECS、ECRを使ってコンテナイメージをデプロイして運用するのですが、

AWS以外では、Kubernetes+Dockerで運用するのが一般的らしい。

OSを仮想化するのはVMでもできるけど、

Dockerの方が最小限のリソースで複数稼働させることができます。

デプロイ時にコンテナイメージを作成してしまえば、

スケールイン、アウトも簡単にできてしまいます。

ということで、まずはPHPを動かすだけのDockerを使ってみる。

使用した環境はWSL環境。

Dockerデスクトップインストール済み。

WSLにログインして、ディレクトリ作成。

~/dockerenv/ex01$ 

Dockerfileを作成。

FROM php:7.4-apache

LABEL maintainer="username@hogehoge.com"
LABEL version="1.0"
LABEL description="シンプルなPHPイメージです。"

WORKDIR /tmp/mydir

イメージをビルド

~/dockerenv/ex01$ docker image build -t ex01/php:1.0 .

Dockerを起動し、Docker内のbashを起動

~/dockerenv/ex01$ docker container run -it --rm ex01/php:1.0 /bin/bash

Docker内のphpのバージョン表示、現在ディレクトリ表示、Dockerを抜ける

root@212df36f6268:/tmp/mydir# php -v
PHP 7.4.33 (cli) (built: Nov 15 2022 06:03:30) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
root@212df36f6268:/tmp/mydir# pwd
/tmp/mydir
root@212df36f6268:/tmp/mydir# exit
exit

イメージの情報表示

~/dockerenv/ex01$ docker image inspect ex01/php:1.0 

LabelsブロックにDockerfileの内容が表示されていればOK

"Labels": {
                "description": "シンプルなPHPイメージです。",
                "maintainer": "username@hogehoge.com",
                "version": "1.0"
            },

【数学】【PYTHON】法線ベクトル(ベクトルの外積)を求める

法線ベクトルとは、2つのベクトルから計算されるベクトルで、

その向きは2つのベクトルの表現される面とは垂直のベクトルとなり、

その向きは「右ねじの法則」と呼ばれる法則によって決まります。

>>> import numpy as np
>>> a = np.array([0, 1, 2])
>>> b = np.array([2, 0, 0])
>>> np.cross(a, b)
array([ 0,  4, -2])

法線ベクトルの計算はcross()関数で求めることができます。

便利。

法線ベクトルはCGの世界では、法線ベクトルと光りのベクトルによって、

画面に表示する色や明るさなどを計算するのに使用されます。

【DIRECTX】DIRECT2Dを試す、その6(楕円を描く)

【DirectX】DIRECT2Dを試す、その5(直線を引く) | 自分、ぼっちですが何か? (taki-lab.site)

今回は楕円を描きます。

これまで通り、D2D_drawing()を修正します。

void D2D_drawing(ID2D1HwndRenderTarget* pRT)
{
	pRT->BeginDraw();
	pRT->Clear(D2D1::ColorF(D2D1::ColorF::White));

	ID2D1SolidColorBrush* mybrush;
	pRT->CreateSolidColorBrush(
		D2D1::ColorF(D2D1::ColorF::Black, 1.0f),
		&mybrush);
	D2D1_ELLIPSE ellipse = D2D1::Ellipse(D2D1::Point2F(100.0f, 100.0f), 75.0f, 10.0f);
	pRT->SetTransform(D2D1::Matrix3x2F::Translation(0, 0));
	pRT->FillEllipse(ellipse, mybrush);
	pRT->SetTransform(D2D1::Matrix3x2F::Translation(200, 10));
	pRT->DrawEllipse(ellipse, mybrush, 1.0f);

	pRT->EndDraw();
}

まず、構造体D2D1_ELLIPSEなんですが、このように定義されています。

typedef struct D2D1_ELLIPSE {
    D2D1_POINT_2F point;
    float radiusX;
    float radiusY;
} D2D1_ELLIPSE;

この構造体は、中心座標 (point) と、 X 方向と Y 方向の半径 (radiusXradiusY) を表しています。X 方向と Y 方向の半径が等しい場合は、円を表します。

楕円を描くときは、DrawEllipse()を、塗りつぶした楕円を描くときはFillEllipse()を使用します。

void DrawEllipse(
  const D2D1_ELLIPSE &ellipse,
  ID2D1Brush *brush,
  FLOAT strokeWidth = 1.0f,
  ID2D1StrokeStyle *strokeStyle = NULL
);
  • ellipse: 描画する楕円を表す D2D1_ELLIPSE 構造体の参照。
  • brush: 描画に使用するブラシのポインタ。このブラシを使用して、楕円の塗りつぶし色を指定します。
  • strokeWidth (省略可能): 楕円の輪郭線の太さを表す浮動小数点値。デフォルト値は 1.0 です。
  • strokeStyle (省略可能): 楕円の輪郭線のスタイルを指定するための ID2D1StrokeStyle インタフェースへのポインタ。デフォルト値は NULL です。
HRESULT FillEllipse(
  D2D1_ELLIPSE ellipse,
  ID2D1Brush *brush,
  FLOAT strokeWidth = 1.0f,
  ID2D1StrokeStyle *strokeStyle = NULL
);

パラメータはDrawEllipse()と同じですね。

SetTransform()は図形の表示位置を設定しています。

第二パラメータにTranslation()の値を入れることで、平行移動変換マトリクスを作成して、それを使用して座標変換して表示してくれています。

【数学】【PYTHON】2つのベクトルのなす角度を求める。

この公式で求めることができます。

このケースを解いてみると、

>>> import math
>>> import numpy as np
>>> a = np.array([2,7])
>>> b = np.array([6,1])
>>> c = np.array([2,3])
>>> d = np.array([6,5])
>>>
>>> va = b - a
>>> vb = d - c
>>>
>>> norm_a = np.linalg.norm(va)
>>> norm_b = np.linalg.norm(vb)
>>>
>>> dot_ab = np.dot(va, vb)
>>>
>>> cos_th = dot_ab / (norm_a * norm_b)
>>> rad = math.acos(cos_th)
>>> deg = math.degrees(rad)
>>> print(deg)
82.8749836510982
>>>

変数a,b,c,dは各座標の値を示しています。

va,vbはベクトルの成分を計算しています。

引き算で計算できるのは便利。

np.linalg.norm()でベクトルの大きさを求めています。

ベクトルの各成分を2乗した和の平方根を計算してくれます。

np.dot()はベクトルの内積を求めています。

cos_thには上の公式を使用した計算結果が入ります。

これをcosの逆関数を計算し、ラジアンを角度に変換すると、

およそ83度という計算結果となります。

【DirectX】DIRECT2Dを試す、その5(直線を引く)

今回は画面に直線を引きます。

変更する箇所は、前回のソースコードのD2D_drawing()の中身。

void D2D_drawing(ID2D1HwndRenderTarget* pRT)
{
	pRT->BeginDraw();
	pRT->Clear(D2D1::ColorF(D2D1::ColorF::White));
	ID2D1SolidColorBrush* mybrush;
	pRT->CreateSolidColorBrush(
		D2D1::ColorF(D2D1::ColorF::Black, 1.0f),
		&mybrush);
	pRT->DrawLine(
		D2D1::Point2F(10.0f, 50.0f),
		D2D1::Point2F(250.0f, 100.0f),
		mybrush,
		10.0f
	);
	pRT->EndDraw();
}

線を引くには、DrawLine()というメソッドを使います。

引数はこうなってます。

第一引数、第二引数は直線の始点と終点ですね。

第三引数のブラシは、CreateSolidColorBrush()で作成したデータです。

第四引数は線の太さですね。

第五引数は特に説明無かった。

【数学】【PYTHON】ベクトルの演算

ベクトルの演算を行うときは、成分同士を足したり引いたりして計算するんですが、

Numpyの配列を使えば、そういった演算もライブラリでやってくれます。

便利。

>>> import numpy as np
>>> a = np.array([2, 2])
>>> b = np.array([2, -1])
>>> a+b
array([4, 1])
>>> a-b
array([0, 3])
>>> 2*a
array([4, 4])
>>>