NI製品ディスカッション

キャンセル
次の結果を表示 
次の代わりに検索 
もしかして: 

オブジェクト指向(クラスの)の使い方(非線形LMフィティング関数を使ったデータ解析のプログラム)

解決済み
解決策を見る

初めて投稿いたします。


LabVIEWの非線形LMフィティング関数を使ったデータ解析のプログラムを作成しています。
いろいろなフィティングモデル関数を今後も増やして行きたいので、フィティングの部分をオブジェクト指向(
クラス)を使ったもので作成いたしました。
(ケースストラクチャーでフィティング関数を選ぶのではなく、ダイナミックディスパッチを使っています。)

サンプルファインダーにあるオブジェクト指向のサンプルプログラムは、複雑すぎるため良く分からなかったの
で、とりあえずデモ版を作ってみました。
今後、フィティングモデル関数を追加していきたいと思いますが、まずこのデモ版でクラスの使い方やその他な
んでもご意見を頂けたらと思います。


作ったプログラム概要
Labview2012 SP1で作成しています。
(O_DemoFitプロジェクトファイルを開いてください。その中のO-DFMain.Viがメインプログラムです。)

デモデータを分布関数(Gauss関数とJohnson SU分布)でFittingを行うプログラムです。
ステートマシーンを使っています。

デモデータはJohnson SU分布で作ったものです。
Johnson SU分布は、単分布でいろいろな形(左右非対称)が作れる分布関数のようです。
http://www.ntrand.com/jp/johnson-su-distribution/
(今後、デモデータではなくデータの読み込み部分を作成するつもりです。)

・Fittingを行うには、まず初期値を決めるためのステートがあります。
・その値を用いてFittingを行います。

クラスとして
Functionクラスを親として
Gaussクラス
JSUクラスが子です。

オブジェクト指向で重要なカプセル化についてはこのプログラムでは考えていません。
カプセル化を行うとアクセサーの作成、外部とのやり取りメソッドを作らなければならなくなるので、今回の場
合は作成していません。また、LabVIEWのサンプルを見ると多くのアクセサー(クラスデータへのアクセス)の
アクセススコープがパブリックでしたので、そのような使い方にしています。

よろしくお願いします。

 

すべてをダウンロード
メッセージ1/17
6,477件の閲覧回数

初めての投稿でしたので、わからず間違えて同じファイルを2つ添付してしまいました。

同じファイルですので、どちらかを開いていただければと思います。

 

よろしくお願いします。

 

 

0 件の賞賛
メッセージ2/17
6,473件の閲覧回数

Fitting関数クラスをダイナミックにロードするために、Factory methodの作成を試みましたが、このプログラムが正しいかどうか?機能しているかどうか(選んだクラスのみロードされる)確かめる方法がよく分かりません。確認方法を教えていただけると大変助かります。

作成したプログラムを添付いたします。

 

よろしくお願いします。

0 件の賞賛
メッセージ3/17
6,411件の閲覧回数

私の知っている方法は、

 

1.プロジェクトをとじて、メインVIのみを立ち上げる。

2.表示→LabVIEWクラス階層

3.このとき、メモリにロードされているクラスのみが表示されているはずです。

4.ファクトリパターンにより今後クラスがロードされた場合、クラス階層にそのクラスが表示されます。

 

*プロジェクトを閉じなくてもよかった気がしたのですが、手元の実験ではそうはならなかったです。

TailOfGon
Certified LabVIEW Architect 2013
0 件の賞賛
メッセージ4/17
6,408件の閲覧回数

ご教授ありがとうございます。

手順のとおり確認を行いました。

O_DemoFitでは、実行と同時に子クラスのGauss,JSUが呼び出されていました。

O_DemoFit2では、実行と同時に子クラスのJSUが呼び出されていました。

この理由としては、デモデータを作る際に、JSUクラス内のモデル関数のViを呼び出していたことによるものだと考えられましたので、クラス外に新しくモデル関数を作りました。

そうしたところ、実行時には、親クラスのFunctionのみ呼び出されており、各フィティングボタンを押すと、対応する子クラスが呼び出されるようになりました。

改良版のファイルを添付いたします。

これにより、ファクトリーメソッドの実装を確認することができました。

ありがとうございました。

 

0 件の賞賛
メッセージ5/17
6,375件の閲覧回数

Gyutan様

 

お役に立ててよかったです!LabVIEWではクラス内のVIが一個でもメモリにロードされると引きつられてクラス内の全VIがメモリにロードされます。これはlvlibとは異なる動作ですね。lvlibのVIは一個ずつメモリにロードできるのです。

TailOfGon
Certified LabVIEW Architect 2013
0 件の賞賛
メッセージ6/17
6,369件の閲覧回数

無限区間で定義された連続分布関数の、データ解析のプログラムができましたので参考までにアップしておきます。

このプログラムは
フィティング関数をクラスで作成しています。
Factory methodを使い動的にクラスを呼び出しています。

無限区間で定義された連続確率密度関数として
Johonson SU分布
Gumbel Type I分布
この2つはLabviewの数学の確率にはない関数です。

Logistic分布
Laplace分布
Cauchy分布
はLabviewのライブラリーにあるViを使っています。

なお、連続確率密度関数の平均、標準偏差、歪度、尖度などについては下記のHPを参照してください。
http://www.ntrand.com/jp/gallary-of-distributions/

O_DemoFit6のプロジェクトファイルを開いていただいて、O_DFMain6を開いてください。
Data Loadのテストサンプルとして、フォルダー内にあるTestdataを使用してください。

メッセージ7/17
6,285件の閲覧回数

面白い試みですね。スマイリー とてもハッピー 機能追加が容易にできるため私もオブジェクト指向をよく使用しています。

 

「LVクラス名を取得」を使うとクラス名を取り出すことができるので、プライベートデータにクラス名を入力したりクラス名を変更したときにつじつまを合わせる手間が省けます。

 

機能追加のたびにMain VIを編集する手間(イベントケースの追加・タイプ定義の編集・ボタンの追加)を省きたい場合は、たとえば以下のようなUIにして、"Initialize" の時にリストボックスの内容を更新させます。アプリケーションフォルダ内のLVCLASSファイルを捜索してクラス名の配列を作ればよいのですが、"Function.lvclass"だけ無視するように気を使う必要があります。

 

Capture.PNG

 

 

TailOfGon
Certified LabVIEW Architect 2013
メッセージ8/17
6,258件の閲覧回数

TailOfGon様

NIのオブジェクト指向の講習を受けて、私もこれはつかえると思い、いざ、と取り掛かりましたが、思った以上に苦戦しました。また、簡単なサンプルがなかったので、皆さんの理解の助けになればと思い、私の勉強がてら投稿しております。

TailOfGon様のご指摘の通り、クラスを増やすごとに、Main VIを編集する手間が増えます。また、私の方法では、UIがボタンだらけになってしまいます。
ご提案の通りであればUIもすっきりいたしますし、手間もだいぶ省けます。

このアイデアをまねしたいのですが、両方法の実装の仕方がわかりません。
もしよろしければ、ご教授いただけると大変ありがたいです。

0 件の賞賛
メッセージ9/17
6,226件の閲覧回数
解決策
トピック作成者Gyutanが受理

オブジェクト指向の講習を受けてここまで作ってしまうのは率直にすごいと思います。これからこのプロジェクトが発展していくのが楽しみです。スマイリー とてもハッピー

 

リストボックスのところだけを実装してみました。

 

Concrete Functionsというサブフォルダにすべての具象クラスを入れています。Get Functions.viで、そのサブフォルダ内に絞りクラスファイルを捜査してパス配列およびファイル名の配列を取り出します。ファイル名の配列はリストボックスの内容にするため、プロパティノードを使用します。パス配列は後で使用するのでステートデータに入れてしまいます。

 

実際にApplyボタンを押すとエラーが出ますが、これは各クラスのメソッドがアプリケーションディレクトリを基準とした相対パスを使っているのと、私がフォルダを移動してしまったために起きています。

 

アドバイスをさせていただきますと、SetPara.viの中でアプリケーションディレクトリのパスを使っていますね。これはあまりお勧めできません。クラス内のVIから同クラス内の別のVIを参照するときに、アプリケーションディレクトリを基準にすると、後でクラスフォルダを移動した時につじつまを合わせる必用がでてきます。クラスを含むフォルダ(たとえばLogisticフォルダ)は後でフォルダごと移動してもメソッドVIの実行に影響がないようにするべきです。そのためには、VIパス(現在のVIパスという関数があります。)を基準にするとよいと思います。たとえば以下のようにできます。(以下は添付ファイルには実装されていません。)

 

Capture2.PNG

 

 

または、別のテクニックでVIリファレンスを開く関数にパス定数を直接渡します。(文字列定数だと動作が異なるので注意!)VIリファレンスとパス定数の組み合わせを使うと、関数は呼び出すVIと同じディレクトリにあるVIを見つけてリファレンスを開いてくれます。上の例よりもこれがお勧めです。

Capture3.PNG

 

さて、LM ModelというVI名をクラスのプライベートデータに入れるべきかどうかという点も気になるところですね。外部からLM Modelを変更することがないのであればこれは定数扱いなのでプライベートデータに入れる必要はありません。Gaussオブジェクトをたくさん作った時に”LM model function Gauss.vi"という文字列のコピーがたくさんできてしまいます。このときメモリの使用量が増えてしまいます。(もちろん本例ではあまり気にすることはないのですが、基本的な考え方として。)

 

 

TailOfGon
Certified LabVIEW Architect 2013
メッセージ10/17
6,211件の閲覧回数