Cucco’s Compute Hack

コンピュータ関係の記事を書いていきます。

Ubuntu 16.04 NVIDIA driver Install

Ubuntu16.04インストール直後は、GPUのドライバがないので、ドライバを更新する。
ログイン画面が開かない場合は、仮想コンソールを開く。Ctrl + Alt + F1。
次のようなエラー(LVMの場合)?の場合も対象。

lvmetad is not active yet; using direct activation during sysinit

インストールするドライバをリポジトリから探す

$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt-get update
$ sudo apt-cache search nvidia-3
nvidia-304-dev - NVIDIA binary Xorg driver development files
nvidia-331 - Transitional package for nvidia-331
nvidia-331-dev - Transitional package for nvidia-340-dev
nvidia-331-updates - Transitional package for nvidia-340
nvidia-331-updates-dev - Transitional package for nvidia-340-dev
…
nvidia-375 - NVIDIA binary driver - version 375.26

インストール

NVIDIAのサイトでも配っていたversion 375.26をインストール。

$ sudo apt-get install nvidia-375

SQL操作で列の最大値を得る

ある列が最大の列の値を取ってくる場合、以下は間違い。

mysql> select id,time from table_sec where time=max(time);
ERROR 1111 (HY000): Invalid use of group function

列名に対してMAXを適用するなんて不思議な感じ。

mysql> select id,max(time) from table_sec;
+----+---------------------+
| id | max(time)           |
+----+---------------------+
|  1 | 2016-12-12 11:00:15 |
+----+---------------------+
1 row in set (0.00 sec)

mysqlでのテーブルの1対多のjoin。

mysqlでのテーブルの1対多のjoin。

TABLE_SECには、5秒ごとのデータが入っている。
TABLE_HOURには、1時間ごとのデータが入っている。

10:00:06の時点では、10:00:00からの5秒間のデータは確定しているが、
10:00:00から1時間のデータは確定していない。
そのため、9:00:00から1時間のデータを参考の資料として対応づける。

TABLE_SECでは、timeShift1、timeShift2は使用していないが、同じテーブル構成になるように定義を残している。
TABLE_HOURでは、timeShift1は1時間先、timeShift2は2時間先の時刻を指している。

INNER JOINで2つの条件で1件に絞ってJOINしている。

# -*- coding: utf-8

import mysql.connector
import datetime

config = {
    'user': 'root',
    'password': 'Password',
    'host': 'localhost',
    'database':'testdb',
    'charset':'utf8'
}
cnx = mysql.connector.connect(**config)
cur = cnx.cursor(buffered=True)

sql = 'DROP TABLE IF EXISTS TABLE_SEC;'
cur.execute(sql)
cnx.commit()

sql = 'DROP TABLE IF EXISTS TABLE_HOUR;'
cur.execute(sql)
cnx.commit()

sql = 'CREATE TABLE IF NOT EXISTS TABLE_SEC (id INT UNSIGNED NOT NULL AUTO_INCREMENT,\
							time DATETIME DEFAULT NULL, \
							timeShift1 DATETIME DEFAULT NULL, \
							timeShift2 DATETIME DEFAULT NULL, \
							volume INT UNSIGNED DEFAULT NULL,\
							valid INT UNSIGNED DEFAULT NULL ,\
							primary key(id),\
							unique (time));'
cur.execute(sql)
cnx.commit()

sql = 'CREATE TABLE IF NOT EXISTS TABLE_HOUR (id INT UNSIGNED NOT NULL AUTO_INCREMENT,\
							time DATETIME DEFAULT NULL, \
							timeShift1 DATETIME DEFAULT NULL, \
							timeShift2 DATETIME DEFAULT NULL, \
							volume INT UNSIGNED DEFAULT NULL,\
							valid INT UNSIGNED DEFAULT NULL ,\
							primary key(id),\
							unique (time));'
cur.execute(sql)
cnx.commit()
sql='INSERT INTO TABLE_SEC (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T9:59:55","2016-12-12T10:00:00","2016-12-12T10:00:5",1,0);'
cur.execute(sql)
cnx.commit()
sql='INSERT INTO TABLE_SEC (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T10:00:00","2016-12-12T10:00:05","2016-12-12T10:00:10",1,1);'
cur.execute(sql)
cnx.commit()
sql='INSERT INTO TABLE_SEC (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T10:00:05","2016-12-12T10:00:10","2016-12-12T10:00:15",1,2);'
cur.execute(sql)
cnx.commit()
sql='INSERT INTO TABLE_SEC (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T11:00:10","2016-12-12T11:00:15","2016-12-12T11:00:20",1,3);'
cur.execute(sql)
cnx.commit()
sql='INSERT INTO TABLE_SEC (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T11:00:15","2016-12-12T11:00:20","2016-12-12T11:00:25",1,4);'
cur.execute(sql)
cnx.commit()
sql='INSERT INTO TABLE_SEC (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T10:00:20","2016-12-12T10:00:25","2016-12-12T10:00:30",1,5);'
cur.execute(sql)
cnx.commit()

sql='INSERT INTO TABLE_HOUR (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T8:00:00","2016-12-12T9:00:00","2016-12-12T10:00:00",2,8);'
cur.execute(sql)
cnx.commit()
sql='INSERT INTO TABLE_HOUR (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T9:00:00","2016-12-12T10:00:00","2016-12-12T11:00:00",2,9);'
cur.execute(sql)
cnx.commit()
sql='INSERT INTO TABLE_HOUR (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T10:00:00","2016-12-12T11:00:00","2016-12-12T12:00:00",2,10);'
cur.execute(sql)
cnx.commit()
sql='INSERT INTO TABLE_HOUR (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T11:00:00","2016-12-12T12:00:00","2016-12-12T13:00:00",2,11);'
cur.execute(sql)
cnx.commit()
sql='INSERT INTO TABLE_HOUR (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T12:00:00","2016-12-12T13:00:00","2016-12-12T14:00:00",2,12);'
cur.execute(sql)
cnx.commit()

#ここからが本題。
#SELECT * FROM TABLE_HOUR INNER JOIN TABLE_SEC ON TABLE_SEC.time >=TABLE_HOUR.timeShift1 AND TABLE_SEC.time < TABLE_HOUR.timeShift2;
sql='SELECT TABLE_SEC.id,TABLE_SEC.time,TABLE_HOUR.time FROM TABLE_HOUR INNER JOIN TABLE_SEC ON TABLE_SEC.time >=TABLE_HOUR.timeShift1 AND TABLE_SEC.time < TABLE_HOUR.timeShift2;'

cur.execute(sql)
record = cur.fetchone()
while record!=None:
	print(record)
	record = cur.fetchone()

cur.close()
cnx.close()

結果

(1, datetime.datetime(2016, 12, 12, 9, 59, 55), datetime.datetime(2016, 12, 12, 8, 0))
(2, datetime.datetime(2016, 12, 12, 10, 0), datetime.datetime(2016, 12, 12, 9, 0))
(3, datetime.datetime(2016, 12, 12, 10, 0, 5), datetime.datetime(2016, 12, 12, 9, 0))
(6, datetime.datetime(2016, 12, 12, 10, 0, 20), datetime.datetime(2016, 12, 12, 9, 0))
(4, datetime.datetime(2016, 12, 12, 11, 0, 10), datetime.datetime(2016, 12, 12, 10, 0))
(5, datetime.datetime(2016, 12, 12, 11, 0, 15), datetime.datetime(2016, 12, 12, 10, 0))

pythonで逐次入力に対して移動平均を計算するためのクラス

pythonで、逐次入力に対して移動平均を計算する。
移動平均幅は、コンストラクタの引数に与えておく。

以下、ソース。

# -*- coding: utf-8 -*-

class MovingAverage:
	"""逐次入力に対して移動平均を計算するためのクラス"""

	def __init__(self,size):                  # コンストラクタ
		self.pc = 0
		self.data=[0]*size	#リングバッファとして使う
		self.size=size
		self.full=False

	def put(self,value):
		self.data[self.pc]=value
		self.pc=self.pc+1
		if self.pc==self.size:
			self.pc = 0
			self.full=True
		return self.full

	def print(self):
		#デバッグ向けリングバッファの中身確認用
		print(self.data)

	def average(self):
		if self.full:
			return sum(self.data)/self.size
		else:
			#入力が足りないときにも一応値を返してみる。
			return sum(self.data)/self.pc

def main():
	mv2=MovingAverage(3)
	
	mv2.put(4)
	mv2.print()
	print(mv2.average())
	mv2.put(5)
	mv2.print()
	print(mv2.average())
	mv2.put(6)
	mv2.print()
	print(mv2.average())
	mv2.put(7)
	mv2.print()
	print(mv2.average())

if __name__== '__main__':
    main()

実行結果

C:\Python34>C:\Python34\python.exe C:\Python34\movingaverageclass.py
[4, 0, 0]
4.0
[4, 5, 0]
4.5
[4, 5, 6]
5.0
[7, 5, 6]
6.0

Matlab 2016bのwebreadがおかしい

Matlab 2016bのwebreadの動きがおかしかったのでメモ。

問題

Matlab 2016aでは正しく動いていたのに、Matlab 2016bにあげたらbad requestが返ってくるようになった。

原因?

URLの中にある時刻の表現の中で%3Aのエンコードがおかしなことになってることが判明。
URLの中に%3Aを含めると%253Aになったり、:(コロン)で表現するとコロンのままで、%3Aにならなかったり。

暫定対策

C:\Program Files\MATLAB\R2016b\toolbox\matlab\external\interfaces\...
webservices\http\+matlab\+net\QueryParameter.m(429,9)
noEncodeCharsの'/?'を'/?%'に変更して、%を%のままエンコードしないように指定すると、とりあえず動いた。

メモ

アクセス権がないので、Administrator権限で、編集権限を与えてから編集しましょう。

PythonからMatlabの関数を呼び出す

matlab.engineのインストール

管理者権限で起動したコマンドプロンプトで以下を実行

cd "C:\Program Files\MATLAB\R2016a\extern\engines\python\"
C:\Python34\python.exe "C:\Program Files\MATLAB\R2016a\extern\engines\python\setup.py" install

なぜか「ImportError: No module named 'matlab'」

実行するとこんなエラーに。
ImportError: No module named 'matlab'

matlab.engineは以下にあります。
C:\Python34\Lib\site-packages\matlab\engine

解決策1 環境変数でPYTHONPATHを指定して実行する

C:\Program Files\MATLAB\R2016a\extern\engines\python>SET PYTHONPATH="C:\Python34\Lib\site-packages"

C:\Program Files\MATLAB\R2016a\extern\engines\python>"C:\Python34\python.exe" "C:\Users\Cucco\Documents\MATLAB\matengen.py"
[[1.0,2.0,3.0,4.0,5.0]]

解決策2 実行する.pyファイルの中でパスを記載する

# -*- coding: utf-8
import sys
sys.path.append('C:\Python34\Lib\site-packages')
import matlab.engine

eng = matlab.engine.start_matlab()
a = matlab.double([1,4,9,16,25])
b = eng.sqrt(a)
print(b)

実行結果

C:\Python34>C:\Users\Cucco\Documents\MATLAB\matengen.py
[[1.0,2.0,3.0,4.0,5.0]]
参考文献

yak-shaver.blogspot.jp

Matlabで1×Nのサイズのベクトルを2次元配列に変換

まずは変換のルールを確認

3×4の2次元配列を用意。

>> a=[[1 2 3 4]; [5 6 7 8]; [9 10 11 12]]

a =

     1     2     3     4
     5     6     7     8
     9    10    11    12

reshape()で1×Nに変換。列方向に拾って1×Nを作る様子。

>> b=reshape(a,1,[])

b =

     1     5     9     2     6    10     3     7    11     4     8    12

4列の形にしてほしいので、reshape()でn×4に変換。元に戻りました。

>> c=reshape(b,[],4)

c =

     1     2     3     4
     5     6     7     8
     9    10    11    12

元に戻りました。

行方向で2次元配列を拾って行ってほしい

手元にあるデータの並びは行方向に拾った感じのデータなので、それを2次元配列にしたい。

1×nのベクトルを用意。

>> d=[1 2 3 4 5 6 7 8 9 10 11 12]

d =

     1     2     3     4     5     6     7     8     9    10    11    12

あとで転置するので、行を4行になるようにreshape()

>> e=reshape(d,4,[])

e =

     1     5     9
     2     6    10
     3     7    11
     4     8    12

転置すると期待通りに。

>> f=transpose(e)

f =

     1     2     3     4
     5     6     7     8
     9    10    11    12