Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

Boost::ublasで行列計算する その4:粗行列

疎行列
出典: フリー百科事典『ウィキペディアWikipedia)』

疎行列(そぎょうれつ、英: sparse matrix)とは、成分のほとんどが零である行列のことをいう。スパース行列とも言う。
(中略)
数値解析の分野では、疎行列を前提とした解法が多い。疎行列であれば格納方式を工夫することで次元数を増やすことができる上に、ベクトル-行列積が比較的低計算量で求められるためである。

実際、制御などで行列を使おうとした場合動かさない軸が結構多かったりします。
メモリは可能な限り小さくしたほうが何かとありがたいですよね。

実際のところ

格納法は3種あります。
具体的には連想配列、行圧縮格納、座標格納です。

#include <boost/numeric/ublas/matrix_sparse.hpp> 

//...

using namespace boost::numeric::ublas;
mapped_matrix<double> mat_sp_mp(3,100, 3*100);   //  doubleの 3 行 1000 列の疎行列(連想配列式)
compressed_matrix<double> mat_sp_cm (3, 3, 3 * 3);   //  doubleの 3行 x 3列 の疎行列(行圧縮格納式)
coordinate_matrix<double> mat_sp_cm (7, 3, 7 * 3);   //  doubleの 7行 x 3列 の疎行列(座標格納式)

Boost::ublasで行列計算する その3:ゼロ行列・単位行列

実際のところ

ゼロ行列

#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>

int main () {
    using namespace boost::numeric::ublas;
    zero_matrix<double> m (3, 3);
    std::cout << m << std::endl;
}

単位行列

#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>

int main () {
    using namespace boost::numeric::ublas;
    identity_matrix<double> m (3);
    std::cout << m << std::endl;
}

Boost::ublasで行列計算する その2:加法・乗法

#include <iostream>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>

namespace ublas = boost::numeric::ublas;
using namespace std;

int main()
{
    // double型を要素とする行列
    ublas::matrix<double> v(3,3);
    ublas::matrix<double> u(3,3);

    // 各要素の参照と代入
    v(0,0) = 3.0;  v(0,1) = 0.0; v(0,2) = 4.0; 
    v(1,0) = 3.0;  v(1,1) = 0.0; v(1,2) = 4.0; 
    v(2,0) = 3.0;  v(2,1) = 0.0; v(2,2) = 4.0; 

    u(0,0) = 3.0;  u(0,1) = 0.0; u(0,2) = 4.0; 
    u(1,0) = 3.0;  u(1,1) = 0.0; u(1,2) = 4.0; 
    u(2,0) = 3.0;  u(2,1) = 0.0; u(2,2) = 4.0; 

    // ベクトルの演算
    ublas::matrix<double> v1 = v + u;             //加法
    ublas::matrix<double> v2 = v - u;             //減法
    ublas::matrix<double> v3 = v * 2.0;         //整数倍
    ublas::matrix<double> v4 = v / 3.0;         //整数割
    ublas::matrix<double> v5 = prod(v, u) ;  //乗法

    cout << "v1 : " << v1 << endl;
}

Boost::ublasで行列計算する その1:行列を生成

BoostのサブライブラリであるuBlasでは行列やベクトルのような線形代数の計算を高速かつ見通しよく実施することができます。

実際のところ

導入

Ubuntuでの導入なら、apt-get経由でlibboost-devを使ったほうが楽です。
私のように、単に試したいという動機ならビルドしようとしたりすると無闇に時間がかかります(

$ sudo apt-get install libboost-dev

サンプル

公式のサンプルでは、こんな感じの例が提示されています。

#include <iostream>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/io.hpp>

namespace ublas = boost::numeric::ublas;

int main()
{
    // double型を要素とする3次元ベクトル
    ublas::vector<double> v(3);

    // 各要素の参照と代入
    v[0] = 3.0; // x
    v[1] = 0.0; // y
    v[2] = 4.0; // z

    // 出力ストリーム
    std::cout << v << std::endl;
}
[3](3,0,4)

行列の場合は以下のような感じで

#include <boost/numeric/ublas/matrix.hpp>

//...

ublas::matrix<double> matA(3,3);

//...

//初期化
	for(int i = 0; i < 3; i++){
		for(int j = 0; j < 3; j++){
			matA(i,j) = i+j;
		}
	}

SpreadSheetで開始日と終了日から色つきバーめいたものを入れる

shuzo-kino.hateblo.jp
shuzo-kino.hateblo.jp

の流れで……

実際のところ

f:id:shuzo_kino:20181028235542p:plain
画像のように、一列目に日付、C行に開始日、D行に終了日がある状態で

=IF(AND( (INDIRECT(ADDRESS(row(),3)) <= F$1),(INDIRECT(ADDRESS(row(),4)) >= F$1) ), "1", "")

これで数値が記入された所を色付けするようなシートルールをつくっておけば、あとは宜しくバーめいたものができます。

【読書メモ】ICT農業の環境制御システム製作: 自分でできる「ハウスの見える化」

ICT農業の環境制御システム製作: 自分でできる「ハウスの見える化」

ICT農業の環境制御システム製作: 自分でできる「ハウスの見える化」

農業系雑誌「農耕と園芸」に掲載されていた連載をもとにした内容で、農業の実務を踏まえた内容になっています。
著者陣も大学の教員や農研機構の研究員など、やはり農業寄りの布陣。

よくやる作って見た系の本と違い、UECSというスマート農業系業界団体が80年代から研究していたシステムです。

UECSとは、ユビキタス環境制御システム(Ubiquitous Environment Control System)の頭文字を表し、「ウエックス」と読みます。植物を生産するためのガラス室・ハウス(温室)、植物工場などの園芸施設の環境制御を実現するための優れた自律分散型システムです。

UECSとは何か

調べてみるとなんとH8マイコンでの実装もあったようです。
これを今時なもので一通り実装してみた、という内容になっています。
幸い、本誌に掲載されている装置はRasPiやArduinoと今時な構成なので我々でも安心。
その上、この手の作ってみた系で軽視されがちな電源周りについてもちゃんとサージ対策に言及されているなど実戦仕様です。
作り方も写真付きで丁寧に載っているため、当該雑誌のメインターゲットである農家さんも何とか自分でやれるようになっています。(おそらく)

経営サイドからみると……UECSのエコシステム自体が今後案件発掘に使えそうな印象をうけました。
相当実績を積んだフレームワークである上に、
農研機構のような公的バックがあるからなのか、助成金の採択例もそこそこある様子。
Attainment of Japanese Smart Greenhouse by UECS Platform

とある農業系システムの更新を考えていたところだったので、
こちらの編成(とくに電源周り)を次期システムの参考にさせて貰おうと思います。
……プロトコルは……せっかく作ったものがあるので……どうしようかな……。

【自習メモ】typedefとusing

typedefやusingはc/cppにて独自のデータ型を作るときに使用する予約語です。
マイコンを跨いだ実装でありがちな取り扱いビット数の差も、これらを用いて吸収できます。
基本型の機能を極力使いたいけど、一部振る舞いだけ変えたいとき、
あるいはアーキテクチャ間でコードを使いまわしたいがターゲットビットが違う場合なんかで有効です。

実際のところ

typedef

typedefはC言語で構造体を記述するときに出てきますね。
C++の時はクラス使うのでしょうか(C++クソザコ勢

typedef struct
{
  char *cmd;
  void (*func)(char argc, char **argv);
} cmd_t;

static cmd_t cmd_tbl[] = {
  {"start", start},
  {"hello", hello},
  {NULL, NULL}  //いわゆる番兵法
};

他にも、型の宣言でも使えます。

typedef int NewInt;

using

こっちの方が新しい記述です。
C++系の実装なら、優先的にこっちを使った方がいいでしょう。
逆にCだと対応してないコンパイラもあったりします。

先ほどのtypedefでの型定義はusingだと以下のように書く事ができます。

using NewInt = int;