Physics-Station 2

旧 http://physics-station.blogspot.jp/ から当はてなブログに移行しました。間違ってるところがあればコメントください。記述の正確性は保証しません。

JSONファイルの読み取り方 特殊なサンプル1

ヘッダー

#include <picojson.h>

//ファイル読み取り
std::string read_txt(std::string filepath)
{
    std::string str((std::istreambuf_iterator<char>(std::ifstream(filepath))), std::istreambuf_iterator<char>());
    if (str.size() < 3)
    {
        return str;
    }
    if (str[0] == -17 && str[1] == -69 && str[2] == -65)
    {
        return str.substr(3);
    }
    else
    {
        return str;
    }
}

//array型のJSONファイルの読み取り
picojson::array read_json_arr(std::string path)
{
    std::ifstream ifs(path);
    if (!ifs)
    {
        throw std::exception("File cannot be opened.");
    }
    std::string json = read_txt(path);
    picojson::value val;
    std::string err;
    picojson::parse(val, json.c_str(), json.c_str() + strlen(json.c_str()), &err);
    if (!err.empty())
    {
        throw std::exception("JSON format error in");
    }
    picojson::array &obj = val.get<picojson::array>();
    return obj;
}

こういうファイルを読み取りたい

[
  {
    "Nogs": [
      [
        1.0,
        2.0,
        3.0
       ]
    ]
  }
]

読み取り例

void sample()
{
    auto arr = read_json_arr("file.json");
    for (int i = 0; i < arr.size(); i++)
    {
        auto obj = arr[i].get<picojson::object>();
        auto nog = obj.at("Nogs").get<picojson::array>()[0].get<picojson::array>();
        for (int j = 0; j < nog.size(); j++)
        {
            std::cout << nog[j].get<double>() << " ";
        }
        std::cout << std::endl;
    }
}

期待される出力

1.00000 2.00000 3.00000

デバッグしてないので取り扱いに注意して下さい。

Visual Studio の Cross Tools / Native Toolsって何?

  • x86_x64 Cross Tools Command Prompt for VS 2017
    32bit パソコンで64bit パソコン用の実行ファイルを作る
    ただし、64bitパソコンでも動く

  • x64 Native Tools Command Prompt for VS 2017
    64bit パソコンで 64bit パソコン用の実行ファイルを作る

  • x64_x86 Cross Tools Command Prompt for VS 2017
    64bit パソコンで 32bit パソコン用の実行ファイルを作る

  • x86 Native Tools Command Prompt for VS 2017
    32bit パソコンで 32bit パソコン用の実行ファイルを作る
    ただし、64bitパソコンでも動く

普段は ただし の文は無視してもらってかまわない。64bitマシンでも WOW64 というサブシステムのおかげで32bit パソコン用の実行ファイルが動くからである。

参照

方法: 64 ビットの Visual C++ ツールセットをコマンド ラインから有効にする

WOW64 - Wikipedia

f:id:onsanai:20170723013559p:plain

PocoをVisual Studio 2017でとにかくビルドするコマンド

Poco をダウンロードする。

pocoproject.org

Visual Studio 2017の場合

x64 Native Tools Command Prompt for VS 2017

を起動し、次のコマンドを叩く

buildwin.cmd 150 build all both x64 nosamples notests msbuild

Windows SDK バージョン 8.1」が足りないと言われたら、Visual Studio Installer 「C++によるデスクトップ開発」の中から探して入れる。

以上。

オプションの中身? 自分で調べるべし。

参照 mataro777.hateblo.jp

f:id:onsanai:20170723013438p:plain

ATOK2017の日本語入力でVisual Studio 2017のGitのcommitメッセージを書こうとすると異常終了する

Visual Studioが異常終了します。常に異常終了するわけではありません。原因と解決をご存じの方いませんか?

ちなみに、Visual Studio 2015でも同様の現象は起きます。過去にGoogle-IMEでVS2013及びVS2015を使っていましたが、同様の事象は確認していません。

robocopyでフォルダ間をコピーするときのメモ

Windows の堅牢性の高いファイル コピー

よく使うコマンド

robocopy "C:\src" "C:\dst" /S /E /R:0 /NP  1>log.txt

/MIRはdstの削除をするので注意

/S :: サブディレクトリをコピーしますが、空のディレクトリはコピーしません。
/E :: 空のディレクトリを含むサブディレクトリをコピーします。
/R:n :: 失敗したコピーに対する再試行数: 既定値は 1,000,000。
/NP :: 進行状況なし - コピーの完了率を表示しません。

/MIR :: ディレクトリ ツリーをミラー化します (/E および /PURGE と同等)。

bash on Windows

Windows上のUbuntuをアンインストー

lxrun /uninstall /full

Windows上にWindowsをインストー

lxrun /install

32文字のパスワードを32個生成

 pwgen 32 32

Ubuntuのバージョン

cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.5 LTS"

アーキテクチャ

arch
x86_64

OneDriveと同期できません というエラーの解決方法を探索中

X個のファイルが OneDriveと同期できません。

エラー ファイルで遅延が発生しています。

解決方法 ファイルのダウンロード/アップロードは後ほど行います。

f:id:onsanai:20170426213534p:plain:w500

という表示が消えない。

やったことは、メインPC2個で、

onedrive /reset

同期にずいぶん時間がかかったが、同様の表示は出なくなった。

ついでに、使用頻度の低いフォルダを圧縮して一つのファイルにまとめた。これも効いているのかもしれない。

C#でMicrosoft Translator Text APIを使う、2017年1月1日以降も有効な方法

日本語のドキュメントを見つけたぜ、と思ったのだが、罠にかかった。

qiita.com

コメントにも書いたが、この方法は2017年1月1日以降は有効ではない。コメント欄でも紹介されていたが、

Getting Started with Microsoft Translator

に書かれているとおりに進めば良いだろう。

トークンを取得するのに使うのは次の画像のKEY 1というものだ。とにかく、この画面が見れたら勝利は目前だ。ちなみに、KEY 2をつかってもトークンは取得できる。

f:id:onsanai:20170108192503p:plain:w400

トークンを取得する方法はここに書いている。

github.com

翻訳をするためのコアのコードは他の読み物が沢山あるためここでは詳細に書かない。だが、自分のメモのために一応コードを書いておく。追加すべきusingや参照は何も書いていないので注意が必要である。

private string TranslateMethod(string authToken, string translating)
{
    string translated = string.Empty;
    string from = "ja";
    string to = "en";
    string uri = "http://api.microsofttranslator.com/v2/Http.svc/Translate?text=" + 
        System.Web.HttpUtility.UrlEncode(translating) + "&from=" + from + "&to=" + to;

    HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
    httpWebRequest.Headers.Add("Authorization", authToken);
    WebResponse response = null;
    try
    {
        response = httpWebRequest.GetResponse();
        using (Stream stream = response.GetResponseStream())
        {
            DataContractSerializer dcs = new DataContractSerializer(Type.GetType("System.String"));
            translated = (string)dcs.ReadObject(stream);
        }
    }
    finally
    {
        if (response != null)
        {
            response.Close();
            response = null;
        }
    }
    return translated;
}

以上だ。

C++で任意の文字でstringを分割する方法

std::getlineは名前の通りstreamから1行ごとにstringを得る関数だが、デリミタ(delimiter)を指定することも可能である。分かれば簡単。

std::string str = "a_ab_abc";
std::stringstream ss(str);
std::string item;
std::vector<std::string> vitem;
while(std::getline(ss, item, '_')) {
    vitem.emplace_back(item);
}

Visual Studio 2017 + OpenCV 3.2.0 + x64の初期設定 とOpenCVに関する質問の受け付け(コメント欄へ)

Visual Studio 2017 x64 で OpenCV 3.2.0 を使う方法

OpenCVをとにかく使いたい。けどNuGetは使えない、使いたくないっていう人のために、2017/04/13時点での最新版のインストール方法を書きました。2.4.Xの頃と比べて.libの数が減って設定が楽になった。OpenCVReleases - OpenCV libraryWin pack からダウンロードして展開済みだと想定しています。

最終更新:2017/07/12

ディレクトリの設定

プロパティページ -> VC++ディレクトリ -> インクルードディレクトリと、ライブラリディレクトリにそれぞれ

を追加。ただし必要に応じてOpenCVをインストールした場所に変えること

f:id:onsanai:20170413164739p:plain:w300

リンカーの設定

プロパティページ -> リンカー -> 入力 -> 追加の依存ファイルに

を追加。320のところはインストールしたOpenCVのバージョンによって変えること

f:id:onsanai:20170413165027p:plain:w300

PATHの設定

プロパティページ -> 構成プロパティ -> デバッグ -> 環境に

  • PATH=C:\opencv\build\x64\vc14\bin;%PATH%

を追加。ただし必要に応じてOpenCVをインストールした場所に変えること

f:id:onsanai:20170413170027p:plain:w300

テストプログラム

適当にソースファイルを作成し、次のソースコードをコピーする

//インクルードファイル指定
#include <opencv2/opencv.hpp>
//名前空間の指定
using namespace cv;
int main()
{
    //width220, height150の画像を作成
    Mat src = Mat::zeros(150, 220, CV_8UC3);
    //赤色で画像にHello Worldを描く
    putText(src, "Hello World", Point(5, 50), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 200), 2, CV_AA);
    //緑色で画像に線を描く
    line(src, Point(190, 25), Point(190, 45), Scalar(0, 200, 0), 3);
    //要素を直接操作し画像に点を描く
    for (int x = 188; x < 192; x++)
        for (int y = 53; y < 57; y++) //y座標
            for (int i = 0; i < 2; i++) //i < 3にするとBGRすべての要素を200にする
                src.at<uchar>(Point(x * 3 + i, y)) = saturate_cast<uchar>(200);
    //画像を表示
    imshow("", src);
    //ウインドウの表示時間(0はキーが押されるまで閉じない)
    waitKey(0);
    return 0;
}

f:id:onsanai:20170413165228p:plain:w300

実行

プロジェクトを右クリックしてビルド -> デバッグ -> デバッグなしで開始

できたかな?

古い記述

physics-station.blogspot.jp

この旧ブログで受け付けてきた質問を、この新ブログで受け付けます。 OpenCVのインストール方法に限らず、簡単な使い方を含めた一般的な質問も受け付けます。 ページ下部のコメント欄からどうぞ。

YM

2個の自作クラスの配列(std::vector<MyClass>とか)から重複とかを探す

2個の数列(std::vector<int>とか)から重複とかを探す - Physics-Station2 の続き

2個の自作クラスの配列(ベクター)から重複等を探す方法。

#include <algorithm>に便利な関数が用意されている。 ソートして、重複を削除した後、set_intersection, set_union, set_differenceを使えばよいが、自作クラスに比較演算子等がないためそれを別途与える必要がある。この3つの関数に与える演算子は<演算子である。

今回は使い回しが多いため、ラムダ式ではなく関数として与える。 古い例ではインライン関数 inlineが与えられていることがあるが、最近のコンパイラは賢く、勝手に最適化してくれるのでユーザーがわざわざつける必要はない。

f:id:onsanai:20161130074536p:plain:w200

#include <random>
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>

class MyClass
{
public:
    unsigned int id;
    double x, y, ax, ay;
};

bool mycomp_size(const MyClass &a, const MyClass &b) { return (a.id < b.id); }      //大小比較
bool mycomp_equal(const MyClass &a, const MyClass &b) { return (a.id == b.id); }   //イコール比較

void main()
{
    const int Ntrk = 10000000;

    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(0, Ntrk - 1);
    std::vector<MyClass> list1, list2;

    for (int i = 0; i < Ntrk; ++i)
    {
        MyClass t;
        t.id = dis(gen);    //乱数を作成
        list1.emplace_back(t);
        t.id = dis(gen);    //乱数を作成
        list2.emplace_back(t);
    }

    std::sort(list1.begin(), list1.end(), mycomp_size); //ソート
    std::sort(list2.begin(), list2.end(), mycomp_size); //ソート

    std::cout << list1.size() << " (unique)-> ";
    list1.erase(std::unique(list1.begin(), list1.end(), mycomp_equal), list1.end()); //重複を削除
    std::cout << list1.size() << std::endl;

    std::cout << list2.size() << " (unique)-> ";
    list2.erase(std::unique(list2.begin(), list2.end(), mycomp_equal), list2.end()); //重複を削除
    std::cout << list2.size() << std::endl;

    std::vector<MyClass> list_inter; //list1とlist2の両方にある値 (積集合 intersection)
    std::set_intersection(list1.begin(), list1.end(), list2.begin(), list2.end(), std::back_inserter(list_inter), mycomp_size);

    std::vector<MyClass> list_union; //list1かlist2のどちらかに存在する値 (和集合 union)
    std::set_union(list1.begin(), list1.end(), list2.begin(), list2.end(), std::back_inserter(list_union), mycomp_size);

    std::vector<MyClass> list_dif1; //list1にあってlist2にない値 (差集合 dif1)
    std::set_difference(list1.begin(), list1.end(), list2.begin(), list2.end(), std::back_inserter(list_dif1), mycomp_size);

    std::vector<MyClass> list_dif2; //list2にあってlist1にない値 (差集合 dif2)
    std::set_difference(list2.begin(), list2.end(), list1.begin(), list1.end(), std::back_inserter(list_dif2), mycomp_size);

    std::cout << "dif1 + dif2 + inter = union" << std::endl;
    printf_s("%u + %u + %u = %u\n", list_dif1.size(), list_dif2.size(), list_inter.size(), list_union.size());
    ::system("pause");
}

OneDriveで非常に小さいファイルの同期が終わらない問題

OneDrive上でgitのリポジトリを管理している。 そして、頻繁にOneDriveの同期(アップロード)が終わらない問題が発生する。 gitのcommitのタイミングとOneDriveの同期のタイミングが衝突して、システムファイル関係が(MFT マスターファイルテーブルとか?)が変になっているのではないかと推測。 なので、以下のコマンドをWindowsが起動している状態で実行してみた。

chkdsk
chkdsk /scan

をしたら、ちゃんと同期が完了した。なぜだろうね。因果関係は追跡調査していく。

追記:

2017年現在、この問題は発生していない。

tan空間角度と、ラジアン空間の角度の話

3次元角度がtan空間で次のように与えられたとき

ベクトル1

 \displaystyle
  \left( tan\theta _{x1}, tan\theta _{y1}, 1\right)=\overrightarrow {V_1}

ベクトル2

 \displaystyle
  \left( tan\theta _{x2}, tan\theta _{y2}, 1\right)=\overrightarrow {V_2}

角度差は

 \displaystyle
  \Delta tan\theta = \sqrt {\left( tan\theta _{x1} - tan\theta _{x2}\right)^{2}+\left( tan\theta _{y1} - tan\theta _{y2}\right)^{2} }

cosθはドット積を用いて

 \displaystyle
  \overrightarrow {V_1} \cdot  \overrightarrow {V_2} = 
\left| \overrightarrow {V_1}\right| \left| \overrightarrow {V_2}\right| cos\left( \Delta \theta \right)

のように与えられるので、

 \displaystyle
cos\left( \Delta \theta \right) = \dfrac {tan\theta_{x1}tan\theta_{x2}+tan\theta_{y1}tan\theta_{y2}+1} {\sqrt{tan^2\theta_{x1}+tan^{2}\theta_{y1}+1}\cdot \sqrt{tan^2\theta_{x2}+tan^{2}\theta_{y2}+1}}

よってΔθは

 \displaystyle
\Delta \theta = arccos\left( \dfrac {tan\theta_{x1}tan\theta_{x2}+tan\theta_{y1}tan\theta_{y2}+1} {\sqrt{tan^2\theta_{x1}+tan^{2}\theta_{y1}+1}\cdot \sqrt{tan^2\theta_{x2}+tan^{2}\theta_{y2}+1}} \right)

となる

arccosC++だとacosで計算可能。

ELECOM LANケーブル LD-TWST/BM200 レビュー

問:カテゴリ7対応のLANケーブル、20メートル長で10Gbpsは出るのか?

周辺環境によってエラーレートが変わるのは承知しているが、まずは原理的に速度ができるのかを確認した。

使ったのは、

  • ハブ:NETGEAR
  • LANカード:10GbpsIntel 540-t2
  • ツール:CrystalDiskMark 3または4スレッド
  • ディスク:RAMDA 物理メモリ上のRAMディスク

intel X540-T2

intel X540-T2

f:id:onsanai:20161109161206p:plain:w500

f:id:onsanai:20161109161209p:plain:w500

netstat -sの結果の抜粋

IPv4 統計

  受信したパケット                 = 84892211
  受信したヘッダー エラー          = 0
  受信したアドレス エラー          = 221
  転送されたデータグラム           = 0
  受信した不明プロトコル           = 4
  受信後に破棄されたパケット       = 1418
  受信後に配信されたパケット       = 84891132
  出力要求                         = 10380822
  ルーティング破棄                 = 0
  破棄された送信パケット           = 9
  ルートのない送信パケット         = 0
  再構築が必要                     = 0
  再構築                           = 0
  再構築エラー                     = 0
  正常に断片化されたデータグラム   = 0
  断片化できなかったデータグラム   = 0
  作成された断片                   = 0

IPv4 の TCP 統計

  アクティブ オープン              = 243
  パッシブ オープン数              = 75
  失敗した接続試行数               = 13
  リセットされた接続               = 33
  現在の接続                       = 15
  受信したセグメント               = 84885347
  送信したセグメント               = 61786533
  再送信されたセグメント           = 271


IPv4 の UDP 統計

  受信したデータグラム    = 4086
  ポートなし              = 1339
  受信エラー              = 80
  送信したデータグラム    = 598

答:10Gbpsは出そう。7.5Gbpsは確実に出る。エラーレートも高くない。

仕様通り出るのは当然ではあるが、Amazonなどでは1Gbpsのポート+ルータで1Gbpsが出ました!とかいう報告しかなくて少し心配だった。 だがこれで一安心。

ATOK Syncで環境設定を同期させる方法

ATOK Syncでアップロード+ダウンロードをしたつもりなのに、設定が一部しか同期されないという問題が発生した。

結論から言うと、現時点で、すべての環境設定を同期させる方法はない。

http://potato.2ch.net/test/read.cgi/software/1453634331/651

651 名前:550[sage] 投稿日:2016/02/11(木) 19:28:50.15 ID:jF+1O1lh0
サポートに聞いてみたところ、同期できる設定は
入力・変換>基本
入力・変換>句読点変換
キー・ローマ字・色
だけだそうで。

ATOKプロパティ(環境設定)で変更できる入力・変換の設定やキーカスタマイズなどの情報を同期できます。
酷い宣伝だよ。

ここからなにも変わっていないと思われる。月々500円払って、全部の設定を同期できると思ったら大間違い・・・。

f:id:onsanai:20161106120451p:plain

ここで書いている「環境設定をアップロード」「環境設定をダウンロック」というのは、「ごく一部の環境設定を・・・」に置き換えたほうがよいだろう。

Windowsだけでもいいから、すべての環境設定を同期できるようになりませんかね? ジャストシステムさん。