iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど
BUKURO.swiftは、月に一度、平日の夜に池袋のコワーキングスペースOpenOffice FORESTで開催される、macOS/iOS/watchOS/tvOSプログラマのための勉強会です。
参加費は無料で、各自コワーキングスペースの利用費を払っていただきます。
様々な方が参加者されていまして、業務でアプリケーションを開発されている方、異なるIT分野の方、趣味でプログラミングをされている方などです。
ただ、共通しているのはプログラミングを学びたいということです。
勉強会に参加するということは、広大なプログラミングの学びの領域を手分けして勉強し、得られた知識を共有するということでもありますし、学んだことを他人に教えることによって、理解を深めるということではないかと思っています。
荀子の言葉に、「聞いたことは忘れ、見たことは覚え、行ったことは理解できる。」がありますが、自分もアプリケーション開発をマスターしたいと試行錯誤してきたのですが、うまくいきませんでした。試験がある学生時代と異なり、社会人となった自分にとって、講義形式での勉強は身に入らず、揃えられた材料を使って手を動かしても実は理解できていなかったりと、このことは実感しました。
そんな自分にとって勉強会の発表の場は、自分で自分のケツを叩く良い勉強のの場となりました。
もし、アプリケーション開発をマスターしたいと考えられている方がいらっしゃいましたら、お待ちしております!
勉強会で発表するということを大げさに考えなくてもと思っていまして、ある分野を勉強し理解できたので発表するだけでなく、今取り組んでいることから課題となっていることを説明し、発表者から参加者に質問をするというのもありで、実際、自分をこれによって何度か助けられました。
ですので、もし、敷居が高そうという理由で参加を躊躇されている方がいらっしゃるのでしたら、全然、大丈夫ですよ!と伝えたいです。
勉強会の名前にSwiftがついているので、Swiftでプログラミングしていないと関係ないや!とお考えの方、こちらも大丈夫です。AppleScript関連しか発表されない方もいらっしゃいます!
平日の夜、開催ということで、終了後、帰宅を急ぐ方が多く、懇親会は開催していません。ですが、年末の勉強会では、終了後、有志でささやかな忘年会のようなことをやろうと思っていますので、お声がけを。希望者がいらっしゃらない場合は中止ですが・・・
自分はプログラマがアプリケーションをプログラミングしてリリースするという行為は表現活動という一面があると思っています。
プログラマがプログラミングすることによって喜ぶ方々がいらっしゃるとすれば素晴らしいじゃないですか。
ほぼ毎月、池袋の片隅でBUKURO.swiftの扉を叩いて入ってこられる方をお待ちしています。いつでも大歓迎ですので、ちょっと、ブクロでお茶する感じの軽いノリで、時間があったらで構いませんので、是非!
CloudKitは日記アプリのモデルを格納する場所には向いていないということで、iCloudドキュメントを試してみた。
iCloudコンテナ・ディレクトリにファイルを格納するのだが、このコンテナ、CloudKitで出てきたコンテナと同じ識別子で指す物のようだ。ただ、識別子は同じでも、領域は異なるのだと思う。
以下がファイルに書き込むコードだ。
let containerURL = FileManager.default.url(forUbiquityContainerIdentifier: "iCloud.com.example.KeepADiary")
let documentsURL = containerURL?.appendingPathComponent("Documents")
let fileURL = documentsURL?.appendingPathComponent("my.diary")
/* write */
let todayText = Date().description
do {
try todayText.write(to: fileURL!, atomically: true, encoding: .utf8)
}
catch {
print("write error")
}
このコードは、macOSとiOSで動作するが、macOSで実行した際のfileURLの内容は以下のとおり。
file:///Users/yukio/Library/Mobile%20Documents/iCloud~com~example~KeepADiary/Documents/my.diary
このディレクトリでファイルを確認すると以下のとおり。
$ pwd
/Users/yukio/Library/Mobile Documents/iCloud~com~example~KeepADiary/Documents
$ ls
my 3.diary my 4.diary my 5.diary my 6.diary my 7.diary
ファイル書き込み時に、このディレクトリのファイルを確認したところ、my.diary という名前のファイルが作成されるが、しばらくすると、my 8.diary という風にファイル名が変更される。何故だ!ファイルの上書き防止機能?版管理機能?
私が普段使っている「開発環境」は次のようなものです。
Mac miniは主に事務処理に、MacBook Proでプログラミングしています。開発時は音楽が欠かせませんので、再生機器としてiPhone、聴くためのAirPods、操作するためのAppleWatchも必須です。主に、エアチェックしたNHK FMの番組を聴いています。
自分はUNIX育ちですので、ターミナル操作は苦になりません。ですので、よく使うテキストエディタにはviも入ります。GUIでは、Path FinderとJedit Ωを組み合わせて使っています。Path Finderは最初取っつきにくいのですが、選択したファイルを状況に合わせて選択したアプリで開けるのが便利です。Jedit Ωは普通のテキストエディタとして利用できるので気に入っています。
XcodeはmacOSやiOS開発には必須なので説明は不要でしょう。Macintoshの開発環境はTHINK Cから始まり、MPW、Project Builder、Xcodeと使ってきましたが今のXcodeには満足しています。
Androidの開発はあまりできていないのですが、Android Studioを「素」で使っています。Bitzでは基本ネイティブで開発するようにしていますので、例えば、iOSとソースを共通化するために中間的な環境を利用しないようにしています。少人数での開発でしたら、そちらの方が効率悪いので。
アプリケーションの開発では、画像を扱うことが多く、ペイント系はPixelmatorで、ドロー系はAffinity Designerを使っています。ちょっと、高機能を持て余しているのですが、自分に見合ったものを見つけられていませんので、これを使っています。
これ以外にちょっとした処理の自動化ではperlを使うことが多かったのですが、今は修行をかねて、pythonやruby、Bourne Shell、list、swiftも使うようになりました。別にperlには不満はなく、一時に、自分の主な業務はPerlプログラミングといった方が正確では?という時期もありました。ありがとう、Perl。
Swiftのリファレンスが欲しい!自分好みのものは自分で作れば。そうだ、オープンソースにすれば協力者が現れるかも!
ということで、作成中のリファレンスをgithubにあげました。markdownなので、参加しやすいと思います!
自分の長期的な課題は数式処理と神経回路網だ。後者については、過去何度か挑戦しているが、最近の深層学習ブームのおかげで情報と道具が充実してきたので、またまた、挑戦する。
Accelerate Framework。以前は、CPUの演算アクセラレータを利用する手段でしたが、徐々に数値計算関連のものが追加されていて、今になって分かるのだが、神経回路網関連のものが徐々に用意されている。最上位はCoreMLということになると思うが自分で実装したいということで、線形代数関連を選択する。
CBLASを利用した例が以下だ。
let kSize: Int32 = 15
let kSizeSize: Int = Int(kSize * kSize)
typealias FloatPointer = UnsafeMutablePointer
var matAns = FloatPointer.allocate(capacity: kSizeSize)
var mat1 = FloatPointer.allocate(capacity: kSizeSize)
var mat2 = FloatPointer.allocate(capacity: kSizeSize)
let p = unsafeBitCast(matAns, to: UnsafeMutablePointer.self)
cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,
kSize, kSize, kSize, 1, mat1, kSize, mat2, kSize, 0, p, kSize);
matAns.deallocate(capacity: kSizeSize)
これは辛いがしょうがないと諦めていたが、Developers.IOの記事で、la_object_tを知った。
Developers.IOの記事で紹介されているデバッグ出力用のコードは、古いSwiftのものなので、今時点のものに更新した。
extension la_object_t {
public var rows: UInt {
return UInt(la_matrix_rows(self))
}
public var cols: UInt {
return UInt(la_matrix_cols(self))
}
public var toArray: [Double] {
var arrayBuf = [Double](repeating: 0.0, count: Int(rows * cols))
let status = la_matrix_to_double_buffer(&arrayBuf, cols, self)
return arrayBuf
}
public var matrix: [[Double]] {
var matrix = [[Double]]()
for row in 1...rows {
let firstCol = Int(cols * (row - 1))
let lastCol = Int(cols * row - 1)
let partCols = Array(toArray[firstCol...lastCol])
matrix.append(partCols)
}
return matrix
}
public var matrixDescription: String {
return matrix.reduce("")
{(acc, rowVals) in
acc +
rowVals.reduce(""){(ac, colVal) in ac + "\(colVal) "} +
"\n"
}
}
}
BLASを直接利用する場合、行列のメモリ配列をC言語の二次元配列なのか、Fortranなのかがあるが、la_object_tだと以下のとおり。
var matABuf: [Double] =
[1, 2, 3,
4, 5, 6,
7, 8, 9]
let matA = la_matrix_from_double_buffer(matABuf,
3, /* 行数 */
3, /* 列数 */
3, /* 改行ごとにメモリバッファをスライドさせる幅 */
la_hint_t(LA_NO_HINT),
la_attribute_t(LA_DEFAULT_ATTRIBUTES))
print(matA.matrixDescription)
以下は単位行列。
let matE = la_identity_matrix(3, la_scalar_type_t(LA_SCALAR_TYPE_DOUBLE), la_attribute_t(LA_DEFAULT_ATTRIBUTES))
print(matE.matrixDescription)
これを掛けてみる。
let matT = la_elementwise_product(matA, matE)
print(matT.matrixDescription)
1.0 2.0 3.0
4.0 5.0 6.0
7.0 8.0 9.0
1.0 0.0 0.0
0.0 1.0 0.0
0.0 0.0 1.0
1.0 0.0 0.0
0.0 5.0 0.0
0.0 0.0 9.0
なんか計算できた。
汚いながらもなんとか、ベクトルの足し算。
var matABuf: [Double] =
[1, 2, 3,
4, 5, 6,
7, 8, 9]
let vecA = la_matrix_from_double_buffer(matABuf,
3, /* 行数 */
1, /* 列数 */
3, /* 改行ごとにメモリバッファをスライドさせる幅 */
la_hint_t(LA_NO_HINT),
la_attribute_t(LA_DEFAULT_ATTRIBUTES))
print(vecA.matrixDescription)
var matBBuf: [Double] =
[1, 4, 7,
2, 5, 8,
3, 6, 9]
let vecB = la_matrix_from_double_buffer(matBBuf,
3, /* 行数 */
1, /* 列数 */
3, /* 改行ごとにメモリバッファをスライドさせる幅 */
la_hint_t(LA_NO_HINT),
la_attribute_t(LA_DEFAULT_ATTRIBUTES))
print(vecB.matrixDescription)
let ans = la_sum(vecA, vecB)
print(ans.matrixDescription)
以下が結果。
1.0
4.0
7.0
1.0
2.0
3.0
2.0
6.0
10.0
計算できてるじゃん。
Accelerate Frameworkで行列計算を行うのはBLASというAPIを利用することになるのだが、これが古くからの伝統にのっとったもので使いにくい。そこで、Cocoaで扱いやすくするためにla_object_t という型が用意されている。今回はこれの使い方を試してみるのと、まずは基本的な演算に挑戦する。
XとYという3次元ベクトルを用意する。まずは値のバッファ。
let vecXBuf: [Double] = [20.0, 30.0, 40.0]
let vecYBuf: [Double] = [15.0, 10.0, 5.0]
これを3行1列の行列として生成する。
let vecX = la_matrix_from_double_buffer(vecXBuf, 3, 1, 1,la_hint_t(LA_NO_HINT), la_attribute_t(LA_DEFAULT_ATTRIBUTES))
let vecY = la_matrix_from_double_buffer(vecYBuf, 3, 1, 1,la_hint_t(LA_NO_HINT), la_attribute_t(LA_DEFAULT_ATTRIBUTES))
これを足してみる。
et vecZ = la_sum(vecX, vecY)
print(vecZ.matrixDescription)
以下の結果となった。
35.0
40.0
45.0
Machine Learning Developer Meetup に参加してきた。このイベントは、TensorFlow User Group Tokyoとの共催ということのようだ。
TensorFlow。日本では、数学と物理の教科書で、Tensorをテンソルと訳しているため、テンソル・フローと呼ばれているが、英語ではテンソー・フローということになるようだ。
Googleが開発し、Googleで利用されている機械学習のライブラリで、先日、TensorFlow Liteというモバイル環境に最適かされた実行環境もリリースされて話題となっている。iOSの世界では、CoreMLのモデルを生成するライブラリの一つとして認識されているということになると思う。
本イベントでは、どちらかというと、学習関連の話題が多く取り上げられ、分散化やボトル・ネックの解消などの話題が多かった。
全然ノーマークだったのだが、まずは、ユーザ・グループに参加してみようと思っている。