関数

関数は、ほとんどのプログラミング言語の中核的なものです。以下は、LabTalkでの関数のシンタックスと用法についての説明です。

目次

組み込み関数

LabTalkは、 組み込み関数を使って、多くの操作をサポートしています。関数の一覧およびそれぞれの説明は、関数リファレンスにあります。 次のようなシンタックスで関数を呼び出します。

outputVariable = FunctionName(Arg1, Arg2, ..., Arg N);

以下は組み込み関数の使用例です。

Count (関数) は、ベクターデータ内の要素の数を整数で返します。

// アクティブなワークシートの列Aにある要素の数を返す
int cc = count(col(A));

Ave (関数)は、データセットのグループの平均を計算し、range変数で結果を返します。

range ra = [Book1]Sheet1!Col(A);
range rb = [Book1]Sheet1!Col(B);
// グループの平均値を返す
rb = ave(ra, 5);    // 5 = グループサイズ

Sin (関数) は、入力角度のsinをdouble型で返します。(入力角度の単位は、system.math.angularunitsの値で決まります。)

system.math.angularunits=1;  // 1 = 度数で入力
double dd = sin(45);         // ANS: DD = 0.7071

戻り値の型がデータセットまたは文字列配列である関数の場合、[index] を使用して配列内の対応するデータを取得し、それを式で使用できます。

Unique (関数)は、指定したデータセット内の固有の数値または文字列のリストを返します。

Col(B)=unique(col(A), 2); //列Aの一意の数値を降順で取得。第2引数は降順を意味します

//2番目の引数はスキップされ、出力は昇順になります
//[index] - 出力の1番目の値 (最小値) 
Col(C)[1]=unique(col(A))[1]; //列Cの行1には、Aで見つかった最小の一意の番号が入力されます

//[0] は最後のインデックスなので、 unique(Col(A))[0]はAで見つかった最大の一意の番号を参照
Col(D)=Col(A)-unique(col(A))[0];

ユーザ定義関数

Origin 8.1以降、複数引数のユーザ定義関数がLabTalk でサポートされています。ユーザ定義関数の構文は次のとおりです。

function dataType funcName(Arg1, Arg2, ..., ArgN) {script;}

必要なOriginのバージョン: Origin 8.6 SR0以降

Note:

  1. 関数名は42文字未満にする必要があります。
  2. 引数と戻り値の両方がstring、double、int、dataset、treeデータ型をサポートしています。デフォルトの引数の型はdoubleです。デフォルトの戻り値の型はintです。
  3. デフォルトでユーザ定義関数の引数は値で渡され、関数内のその引数の値は、関数の外部では利用できません。 しかし、リファレンスで渡す引数は、関数内部で引数の値に変わり、関数の外部でも利用できます。外部で利用するにはREFというキーワードを使います。

数値関数の簡単な例をいくつか示します。

// この関数は数値関数の立方根を計算
function double dCubeRoot(double dVal)
{
    double xVal;
    if(dVal<0) xVal = -exp(ln(-dVal)/3);
    else xVal = exp(ln(dVal)/3);
    return xVal;
}
// ここに示す
dcuberoot(-8)=;

以下の関数は、データセットの幾何平均を計算します。

function double dGeoMean(dataset ds)
{
    double dG = ds[1]; 
    for(int ii = 2 ; ii <= ds.GetSize() ; ii++)
        dG *= ds[ii]; // データセット内のすべての値を乗算
    return exp(ln(dG)/ds.GetSize());
}
// 引数はデータセットを返す
dGeoMean(col("Raw Data"))=;

この例は、範囲を引数で受け付けて、その範囲内のデータの平均を返す関数を定義します。

// 範囲の平均を計算
function double dsmean(range ra)
{
   stats ra;
   return stats.mean;
}
// アクティブブックの最初のシートの
// すべての列を指定する範囲を渡す
range rAll = 1!(1:end);
dsMean(rAll)=;

この例は、日付データセット内の特定の曜日の出現を数える関数を定義します。

function int iCountDays(dataset ds, int iDay)
{
    int iCount = 0;
    for(int ii = 1 ; ii <= ds.GetSize() ; ii++)
    {
        if(weekday(ds[ii], 1) == iDay) iCount++;
    }
    return iCount;
}
// ここでは、金曜日を数える
iVal = iCountDays(col(1),6); // weekday(data, 1)で6は金曜日
iVal=;

関数はデータセットを返すこともできます。

// データセットから負の値のみ取得
function dataset dsSub(dataset ds1)
{
    dataset ds2;
    int iRow = 1;
    for(int ii = 1 ; ii <= ds1.GetSize() ; ii++)
    {
        if(ds1[ii] < 0)
        {
            ds2[iRow] = ds1[ii];
            iRow++;
        }
    }
    return ds2;
}
//列1の負の値すべてを列2に割り当て
col(2) = dsSub(col(1));

または、文字列を返します。

// サブ文字列が現れるデータセット内のすべての値を取得
function string strFind(dataset ds, string strVal)
{
    string strTest, strResult;
    for( int ii = 1 ; ii <= ds.GetSize() ; ii++ )
    {
        strTest$ = ds[ii]$;
        if( strTest.Find(strVal$) > 0 )
        {
            strResult$ = %(strResult$)%(CRLF)%(strTest$);
        }
    }
    return strResult$;
}
// "hadron"が現れる列3のすべてのインスタンスを取得
string MyResults$ = strFind(col(3),"hadron")$; // 「$」記号で終わる事に注意
MyResults$=;

リファレンスで引数を渡す

この例は、tree ノードの値を整数(int)(tree変数の1要素)として返す関数を示します。 さらに、リファレンスで渡すことは、REFキーワードを使って示しています。

// 関数定義
Function int GetMinMax(range rr, ref double min, ref double max) {
  stats rr;
  //stats Xファンクションを実行した後、同じ名前を持つ
  //LabTalkのtree変数を作成/更新
  min = stats.min;
  max = stats.max;
  return stats.N;
}

// GetMinMax関数を呼び、ワークシート全体に対する最小値と最大値を探す
double y1,y2;
int nn = getminmax(1:end,y1, y2);
type "Worksheet has $(nn) points, min=$(y1), max=$(y2)";

LabTalk関数でのツリー変数の使用と参照による変数渡しに関する詳細なサンプルを参照して下さい。

リファレンスで文字列の引数を渡す別のサンプルが以下にあり、これは関数呼び出しで、変数の最後に$を付けません。

//最初のシートの範囲文字列を返す
//実際の新しいブックのショートネームがName$で返される
Function string GetNewBook(int nSheets, ref string Name$)
{
	newbook sheet:= nSheets result:=Name$;	
	string strRange$ = "[%(Name$)]1!";	
	return strRange$;
}

上記関数を呼び出すとき、Name$引数が次に示すように、$記号を付けないことが重要です。

string strName$;
string strR$ = GetNewBook(1, strName)$;
strName$=;
strR$=;

データセット関数

Originは、double型の引数を受け付け、double型で返す数学関数もサポートしています。このような関数の一般的なシンタックスは次の通りです。

funcName(X) = expressionInvolvingX.

これらのデータセット関数が定義されるとき、これらを呼び出し、名前でデータセットが作成されます。 このデータセットは、関数と結びつき、Originプロジェクトの一部として保存されます。 一度定義したら、データセット関数は、名前で参照され、組み込み関数のように使用することができます。

例えば、スクリプトウィンドウに次のスクリプトを入力して、Salaryという関数を定義します。

Salary(x) = 52 * x

一度定義したら、次のように関数を呼び出しできます。

Salary(100)=

これは、Salary(100)=5200のような結果となります。 この場合、結果のデータセットは1つの要素のみを持ちます。 しかし、ベクターデータ(またはデータセット)が入力引数として渡されると、出力は入力時と同じ数の要素のデータセットとなります。

他のデータセットと同様、ユーザ定義のデータセット関数は、作図のセットアップのようなダイアログやレイヤnのようなダイアログ内の利用可能なデータ内に表示されます(そして、他のデータセットのようにプロットできます)。

関数が定義されたとき、2Dグラフレイヤがアクティブレイヤの場合、100ポイントのデータセットがX軸スケールを使って、X範囲として作成され、関数データセットが自動的にプロットレイヤに追加されます。

関数グラフテンプレート(FUNCTION.OTP, 標準ツールバーまたはファイル:新規作成からアクセス可能) も作成され、データセット関数をプロットします。

Originの関数グラフの機能は、新しいデータセット関数に組み込みおよびユーザ定義関数の組合せから簡単に作成できます。 さらに、新しく作成した関数はリファレンスに対してすぐにプロットされます。

この機能には以下のどちらかの方法でアクセスできます。

  1. 標準ツールバーの新しい関数ウィンドウボタンをクリックします。 Button New Function.png
  2. Originのドロップダウンメニューからファイル: 新規作成を選び、リストから関数を選び、OKをクリックします。

開いた作図の詳細ダイアログの関数タブに、F1(x) = 5*sin(x)+1 のように関数定義を入力し、OKをクリックします。グラフに関数がプロットされます。

グラフの新しい関数ボタンをクリックして、作図の詳細に別の関数を追加すれば、別の関数を定義できます。 OKを押すと、新しい関数プロットがグラフに追加されます。 他の関数に対しても行う場合には繰り返します。

フィット関数

多くの一般的な関数をサポートするだけでなく、Originは非線形曲線フィットで使用できる自分のフィット関数を作成することができます。 ユーザ定義のフィット関数は、新しいデータセットを生成するのに使われますが、それらを呼び出すのは、特別なシンタックスが必要です。

nlf_FitFuncName(ds, p1, p2, ..., pn)

ここで、フィット関数はFitFuncNameという名前で、dsは独立変数として使われるデータセット、p1--pn はフィット関数のパラメータです。

単純な例として、y切片と勾配が入力パラメータとなるMyLineという単純な直線のフィット関数を定義する場合、アクティブワークシートの列Cを独立変数、列Dを関数出力に使うには、次のように入力します。

// 切片 = 0, 傾き = 4
Col(D) = nlf_MyLine(Col(C), 0, 4)

関数のスコープ

ユーザー定義変数と同様に、ユーザ定義関数は制御可能なスコープを持ちます。ユーザ定義関数は、LabTalkスクリプトをサポートしている場所ならOriginプロジェクトのどこからでもアクセスでき、定義のスコープはこのような使用に適用できます。例えば、double型またはデータセットを返す@glob=1で定義された関数は、値の設定ダイアログの列の条件式で使うことができます。スコープについては、データ型と変数をご覧下さい。

サンプル: 関数のスコープ

@glob=1を使用して、どこでも関数を呼び出せます。

[Main]
	@glob=1;  // 次の関数をセッションレベルとして定義
	function double dGeoMean(dataset ds)
	{
	    double dG = ds[1]; 
	    for(int ii = 2 ; ii <= ds.GetSize() ; ii++)
	        dG *= ds[ii]; // データセット内の全ての値は全て掛け算する
	    return exp(ln(dG)/ds.GetSize());
	}
	// [main]セクション内の関数を呼び出す
	dGeoMean(col(1))=;
[section1]
	// 関数はこのセクションでも呼び出せる
	dGeoMean(col(1))=;

関数が @glob=1なしで *.ogs ファイルに定義されている場合、そのセクション内でのみ呼び出せます。

[Main]
	function double dGeoMean(dataset ds)
	{
	    double dG = ds[1]; 
	    for(int ii = 2 ; ii <= ds.GetSize() ; ii++)
	        dG *= ds[ii]; // データセット内の全ての値は全て掛け算する
	    return exp(ln(dG)/ds.GetSize());
	}
	// [main]セクション内の関数を呼び出せる
	dGeoMean(col(1))=;
[section1]
	// 関数はこのセクションでも呼び出せない
	dGeoMean(col(1))=;  // エラー: Unknown function

@glob=1を使用しないでブロック内で定義されると、そのブロックの外では呼び出せません。

[Main]
{  // 括弧間で関数を定義
	function double dGeoMean(dataset ds)
	{
	    double dG = ds[1]; 
	    for(int ii = 2 ; ii <= ds.GetSize() ; ii++)
	        dG *= ds[ii]; // データセット内の全ての値は全て掛け算する
	    return exp(ln(dG)/ds.GetSize());
	}
}
	// 括弧の外では関数を呼び出すことはできない
	dGeoMean(col(1))=;  // エラー: Unknown function

チュートリアル: 複数の関数機能を使う

次のミニチュートリアルは、Originのプロジェクトレベルにユーザ定義関数を追加し、その関数を使って関数グラフを作成する方法を示しています。

  1. 新しいプロジェクトを開き、Originメニューから表示:コードビルダを選択してコードビルダを開きます。
  2. 左側のツリーパネルのProjectブランチを開き、ProjectEvents.OGS ファイルをダブルクリックして開きます。このファイルはデフォルトで新しいプロジェクトに存在しています。
  3. [AfterOpenDoc] セクションの下に次のコード行を追加します。
    @glob=1;
    Function double myPeak(double x, double x0)
    {
    double y = 10*exp(-(x-x0)^2/4);
    return y;
    }
  4. ファイルを保存し、コードビルダを閉じます。
  5. Originで、プロジェクトを希望の場所に保存します。OGSファイルがプロジェクトと一緒に保存され、ユーザ定義関数がプロジェクト内で利用できるようになります。
  6. 保存したプロジェクトを再び開きます。これがきっかけとなり、[AfterOpenDoc] セクションが実行され、myPeak 関数が定義されます。
  7. 標準ツールバーの2Dグラフ作成ボタンをクリックするか、ファイル:新規作成:関数グラフ:2Dグラフ関数メニューを選択します。
  8. Y(x) =の編集ボックスにmyPeak(x, 3)を入力し、追加をクリックします。グラフ内に関数がプロットされます。
  9. 開いているダイアログで、関数をmyPeak(x,4)に修正します。下のドロップダウンリストでアクティブなグラフに追加を選択しておきます。追加ボタンをクリックします。修正された関数プロットがグラフに追加されます。
  10. プロジェクトを保存して他のユーザと共有できます。myPeak関数はプロジェクトのロード時に定義されるため、プロジェクト内でいつでもアクセスできます。