SSブログ

JavaScriptで "Cubic Hermite Spline補間関数" を作りました。 [プログラミング]

現在も制作中の、インタラクティヴ ディジタル アート作品の為に、JavaScript三次補間関数を作成致しました。
この関数に補間対象の1次元のデータ配列と拡大倍率の値を渡すと、 " 三次Hermite スプライン補間法 " (Cubic Hermite Spline Interpolator / キュービック エルミート スプライン補間法)でデータの内挿を行い、渡された値の間を滑らかに繋ぐ新たな値を生成して、1次元の新たなデータ配列を返却します。

Cubic Hermite Spline Interpolation_SS_(2016_08_01)_1_Cropped_1 黒い背景に水色の角ばった線と橙色の滑らかな曲線が重なりあったグラフとして描かれている。左上には白く光る丸とそこから緑色の曲線が放射されている模様が描かれている。
https://c1.staticflickr.com/9/8752/28065573983_d53a4c160a_o.png
これはグラフをHTML5のCanvas要素内に描画した際のスクリーンショット画像です。
水色の角ばった線が与えたデータを表しております。
橙色の曲線が補間されたデータを表しております。
与えたデータの点を通り、滑らかな曲線を描いております。
このグラフのデータの補間による拡大倍率は12倍です。

オーヴァーシュートとアンダーシュートが出ますので、値域に関しては適切な処理が必要です。

->->
[2016年8月2日追記]
" 三次Hermite スプライン補間関数 " のオプションを追加致しました。
与えられたデータ配列の最初の要素の値と最後の要素の値が滑らかに繋がり、循環するように指定出来ます。
Cubic Hermite Spline Interpolation_SS_(2016_08_02)_1_Cropped_1 黒い背景に青緑色のぐにゃぐにゃに歪んだ滑らかな曲線の円3つ描かれている。右上の歪んだ円の中央には白く光る丸が描かれ、そこから放射状に青色と紫色のリボンの様な曲線が伸びている模様が描かれている。
https://c1.staticflickr.com/9/8654/28701035475_245787f389_o.png
このスクリーンショット画像に描かれている歪んだ円環は、乱数による一様なノイズを複数回、スケールを変えながら滑らかにデータ補間しつつ合成して行ったものを円形に繋いだ曲線です。
円の始点と終点が滑らかに繋がるようにする為に、データ補間のオプションで、ノイズの最初のデータの値と最後のデータの値が循環するように指定したものです。
<-<-
->->
[2017年5月22日追記]
データを循環させる場合の繋げ方が適切でなかったので修正致しました。
データの最初と最後が補間により滑らかに繋がります。
<-<-

私のこのプログラムは行列計算などにはしていないので処理速度は速くはない筈ですが、綺麗に補間出来ます。
また、このコードはもしかすると間違っているかもしれません。

私のブログ記事: とても美しいディジタル アートになりました。
http://crater.blog.so-net.ne.jp/2016-07-26

私のブログ記事: HTML5のCamvasと "JavaScript" で音声処理と画像描画。
http://crater.blog.so-net.ne.jp/2016-06-30

私のブログ記事: "JavaScript" で音と画像を生成するプログラムのソースコード。
http://crater.blog.so-net.ne.jp/2016-06-30-1

この関数の作成の為にWikipediaなどを参照させて頂きました。

"Wikipedia" (English)の "Cubic Hermite spline" のページのURL:
https://en.wikipedia.org/wiki/Cubic_Hermite_spline

以下に自作のソース コードを掲載致します。
自己責任の上で御自由にお使い下さいませ。
当ソース コードには間違いがあるかもしれません。
もし当ソース コードを使用した事による如何なる問題につきましても、私は責任を取る事が出来ません。
御了承下さいませ。

引数は、以下のものと致します。

dataArray:
補間対象の1次元データ配列。

dataArrayLength:
データ配列の最初の要素から数えての補間対象とするデータの要素数。
dataArray[0]からdataArray[15]までを対象とする場合、16という数値を渡す。

scaleFactor:
拡大倍率。
8倍に拡大したい場合、8という数値を渡す。

isDataLoop:
データの最初と最後を循環させる場合、trueを渡し、循環させない場合、falseを渡す。

// 三次Hermite スプライン補間関数を関数式により定義する。
var cubicHermiteSplineInterpolation = function( dataArray, dataArrayLength, scaleFactor, isDataLoop )
{
 var interpolatedDataArray = [];
 var startingTangent = 0;
 var endingTangent = 0;

 if( isDataLoop === true )
 // データを循環させる場合は以下の処理を行う。
 {
  // データの要素を1つ分だけ後ろへ移動する。
  var i = dataArrayLength;
  for( ; i > 0; i-- )
  {
   dataArray[i] = dataArray[i - 1];
  }

  dataArray[0] = dataArray[dataArrayLength]; // 元のデータの最後の要素の値を先頭の要素に複製する。
  dataArray[dataArrayLength + 1] = dataArray[1]; // 元のデータの最初の要素の値を最後の要素の1つ後に複製する。
  dataArray[dataArrayLength + 2] = dataArray[2]; // 元のデータの最初から2番目の要素の値を最後の要素の2つ後に複製する。
  dataArray[dataArrayLength + 3] = dataArray[3]; // 元のデータの最初から3番目の要素の値を最後の要素の3つ後に複製する。

  var j = 0;
  var k = 0;
  for( i = 1; i < dataArrayLength + 2; i++ )
  {
   // 区間の正接の計算を行う。
   startingTangent = 0.5 * (dataArray[i + 1] - dataArray[i - 1]);
   endingTangent = 0.5 * (dataArray[i + 2] - dataArray[i]);

   // 内挿を行う。
   for( j = 0; j < scaleFactor; j++, k++ )
   {
    var x = j / scaleFactor;
    interpolatedDataArray[k] =
     ((1 + 2 * x) * (1 - x) * (1 - x)) * dataArray[i]
     + (x * (1 - x) * (1 - x)) * startingTangent
     + (x * x * (3 - 2 * x)) * dataArray[i + 1]
     + (x * x * (x - 1)) * endingTangent;
   }
  }

  // 最後部の不要になった要素を削除する。
  for( i = dataArrayLength * scaleFactor; i < (dataArrayLength + 1) * scaleFactor; i++ )
  {
   interpolatedDataArray.pop();
  }

  // 返却される配列の要素数は、 'dataArrayLength * scaleFactor' となる。
 }else
 // データを循環させない場合は以下の処理を行う。
 {
  var i = 0;
  var j = 0;
  var k = 0;
  for( ; i < dataArrayLength - 1; i++ )
  {
   if( i === 0 )
   // 最初の区間の設定を行う。
   {
    startingTangent = (dataArray[i + 1] - dataArray[i]);
    endingTangent = 0.5 * (dataArray[i + 2] - dataArray[i]);
   }else if( i === dataArrayLength - 2 )
   // 最後の区間の設定を行う。
   {
    startingTangent = 0.5 * (dataArray[i + 1] - dataArray[i - 1]);
    endingTangent = (dataArray[i + 1] - dataArray[i]);
   }else
   // 最初と最後以外の区間の設定を行う。
   {
    startingTangent = 0.5 * (dataArray[i + 1] - dataArray[i - 1]);
    endingTangent = 0.5 * (dataArray[i + 2] - dataArray[i]);
   }

   // 内挿を行う。
   for( j = 0; j < scaleFactor; j++, k++ )
   {
    var x = j / scaleFactor;
    interpolatedDataArray[k] =
     ((1 + 2 * x) * (1 - x) * (1 - x)) * dataArray[i]
     + (x * (1 - x) * (1 - x)) * startingTangent
     + (x * x * (3 - 2 * x)) * dataArray[i + 1]
     + (x * x * (x - 1)) * endingTangent;
   }
  }
  interpolatedDataArray[(dataArrayLength - 1) * scaleFactor] = dataArray[dataArrayLength - 1]; // 最後の要素の値を代入する。

  // 返却される配列の要素数は、 '(dataArrayLength - 1) * scaleFactor + 1' となる。
 }
 return( interpolatedDataArray ); // 補間された新たな1次元のデータ配列を返却する。
};

Ubuntu 16.04.1 LTSにアップグレードしました。 [PC]

遂に、2016年7月28日に最新の長期サポート版(Long Term Support)のUbuntuである、Ubuntu 16.04 LTS (Xenial Xerus)のポイント リリース、 " Ubuntu 16.04.1 LTS" のアップグレード通知が有効化されました。

私は29日にUbuntu 14.04 LTSからUbuntu 16.04.1 LTSへアップグレード致しました。

しかしながら、色々と特殊な環境にしてしまっていた私の自作PCでは、アップグレードは問題無くは出来ませんでした。
因みに私のPCのハードウェアについては次のページをご覧下さい。

ブログ記事: 自作PCの構成
http://crater.blog.so-net.ne.jp/2014-11-18

私は既にLinux カーネルをヴァージョン 4.2.0に変更してありました。
また、アップグレード前のNvidia GeForce GTX750のドライヴァーは " Graphics Drivers Team " というPPA (Personal Package Archive)のオープンソース ドライヴァーを利用させて頂いておりました。

まず、私はアップグレード通知のダイアログ ウィンドウからアップグレードしようとして " 今すぐアップグレードする " ボタンを押したのですが、ウィンドウが閉じるだけで何も起こりませんでした。

次にGUI アプリケーション ソフトウェアの " ソフトウェアの更新 " でアップデートを全て済ませた後、同ソフトウェアのアップグレード ボタンを押したのですが、やはり何も始まりませんでした。

そこで " 端末 " を開き、以下のコマンドにてアップグレードを実行致しました。
sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
sudo do-release-upgrade

これで無事、Ubuntu 16.04.1 LTSへのアップグレードが開始されました。

アップグレード完了までには1時間以上は掛かりました。
私の場合は途中で " ttf-mscorefonts " という、マイクロソフト社提供のTTF (True Type Font)のEULA (End User Lisence Agreement / 末端利用者向け使用許諾契約書)が表示されましたが、私はこれを使用しないので拒否して先に進めました。
他にも何度か " Yes / No " の問い掛けがございましたので、定期的に画面を確認しながら待ちました。

途中で、 " Secure Boot " (セキュア ブート)に関係する、 " shim-signed " というパッケージに関して、以下の様な内容のメッセージが表示されました。

->->
" UEFI Secure Boot " が有効(Enable)になっている。UEFI Secure Bootはサードパーティ (Third-party)製ドライヴァーの使用と互換性が無い。
UEFI Secure Bootを無効にするとサードパーティ製ドライヴァーを使用出来る。
UEFI Secure Bootを安全に無効にする為に、まずは使い捨てのパスワードを設定し、再起動後にそのパスワードで利用者の確認をする必要がある。
パスワードが認証されればUEFI Secure Bootは無効になり、サードパーティ製ドライヴァーを使用出来るようになるが、これを行わないとサードパーティ製ドライヴァーは利用出来ない。
<-<-

実はアップグレード前に行ったアップデートの際に " shim-signed " の処理中にGUI アプリケーション ソフトウェアの " ソフトウェアの更新 " がフリーズしてしまい、仕方無くPCを再起動した後に、 " 端末 " を開き、 " sudo dpkg --configure -a " で未設定のパッケージの再設定を実行したところ、上記メッセージが表示されたのですが、パスワードの設定をせずに済ませてしまいました。
その後、Ubuntu 16.04.1 LTSへのアップグレード時に再び同メッセージが表れた次第です。

ところで、 " shim-signed " というパッケージは、説明によると、 " Secure Boot chain-loading bootloader (Microsoft-signed binary) " であるとの事です。
以下、私の認識ですが、多分に間違っているかもしれません。
" UEFI Secure Boot " はUEFI対応のWindows OSがインストールされたPCについて、Microsoft社など信用されているところが署名したブート ローダーやカーネル、ドライヴァー プログラムだけが使用出来るようにする為の仕組みであるようです。
Windows OSとUbuntu OSが共にインストールされたデュアル ブート環境などでは、Ubuntu提供元のCanonicalが署名したり、またはMicrosoft社に署名をして貰ったり、有効なディジタル キーをCanonicalが購入したり、有効なディジタル キーのあるブート ローダー コードを使用したりする事でUEFI Secure Bootが有効の状態でUbuntuとサードパーティ製ドライヴァーが動作するようにしていたようです。
ここで、DKMSが問題となります。
DKMS (Dynamic Kernel Module Support)はカーネル ソース ツリーの外部にあるソースのLinux カーネル モジュールを自動的に生成する為の仕組みだそうです。
DKMS モジュールは新しいカーネルがインストールされた時に所有者のマシン上でコンパイルされ、リビルドされる為、これにはCanonicalなどは署名出来ません。
Ubuntu16.04 LTSからはUEFI Secure Bootに関して、ファームウェア、ブート ローダー、OS カーネル、カーネル モジュール、デヴァイス ドライヴァーなどの安全性の検証に以前より厳格な要求をするようになったようです。
その為、UEFI Secure Bootを無効にしないとサードパーティ製ドライヴァーが動作しない場合があるようです。

私の環境で問題になったのは、 " Nvidia Graphics Driver " でした。
私はUEFI Secure Bootを無効にする為に8桁から16桁の使い捨てのパスワードを設定し、アップグレードを続行致しました。

アップグレードを完了する為に再起動を促すメッセージが表れたので、PCを再起動致しました。
そして、UEFI Secure Bootを無効にする為の使い捨てパスワードを確認する画面が表示されました。
パスワードの何番目かの文字を入力せよとの指示があり、これを入力する操作が何度か繰り返された後、確認が出来たとの表示がございました。そして起動プロセスが進みました。
ところが、ここで問題が発生致しました。
" ログイン ループ " です。
起動時のGUIのログイン画面で、端末のパスワードを入力しても、一瞬画面が黒くなった後、直ぐに元のログイン画面に戻ってしまいます。
何度パスワードを入力してもログイン画面に戻される状態です。
今回直面したログイン ループではゲスト ユーザーに切り替えてもログイン出来ませんでした。
ゲスト ユーザーでログイン出来る場合は、ユーザー設定が壊れている事が原因ですので、ユーザー設定を修復しますが、今回の原因は異なるようです。

ログイン画面の解像度が低くなってぼやけた低解像度な画面になってしまっていた事から、やはりNvidiaのヴィデオ カードのグラフィックス ドライヴァー関係の問題であろうと思いました。
" Ctrl + F1 " キーでCUI仮想コンソールのTTY1にログインして別のグラフィックス ドライヴァーをインストールして再起動するなどしてみたのですが改善致しませんでした。
どうやら正しくUEFI Secure Bootを無効化出来なかった事が原因なようですので、これを無効化する事に致しました。
但し、Windows OSがプリインストールされたメーカー製PCはこれを無効化出来ない場合があるようです。
また、Windows 10などとUbuntu 16.04をデュアルブートしたい場合も、UEFI Secure Bootの無効化をWindows OSが許さない為、これも出来ません。
私は自作PCでUbuntu 16.04 LTS単体での使用ですので、UEFIの設定でこれを無効化出来ます。

PC起動時に " Esc, F2, Del " などのキーを押してUEFI (リッチなBIOS)の設定画面を表示させ、そこからUEFI Secure Bootを無効に致します。
私はAsusのマザーボードを使用しているので、 " Boot " タブの " Secure Boot " の項目の " OS Type " の項目を " Windows UEFI mode " から " Other OS " にし、 " Boot " タブの " CSM (Compatibility Support Module) " を " Enabled " にしてから設定を保存して起動致しました。

すると今度は画面の解像度が正常になり、ログイン パスワードを入力すると正しくログイン出来ました。
只、初回の起動には少々時間が掛かりました。

待ちに待ったUbuntu16.04.1ですが、見た目の変化はスクロール ボックスが変わった事やテキスト エディターの " gedit " のボタンやメニューが変わった事位しかまだ分かりません。

USB オーディオ インターフェイスの " CREATIVE USB Sound Blaster Digital Music Premium HD " の光ディジタル出力から音声が正常に出力出来ておりますし、不具合は今のところ全くございません。

過去のブログ記事: Ubuntu LinuxとUSB Sound Blaster Digital Music Premium HDで音を出せた。録音出来た。
http://crater.blog.so-net.ne.jp/2014-09-18-1

アップグレード時に無効にされたPPAも有効化致しました。

これから数年間はこの環境でPCを使用出来そうです。

ところで、UEFI Secure Bootを無効化しない場合は、サードパーティー製のドライヴァーなどが使用出来ない場合がある訳ですが、これは困る人も居るのではないかと思います。

->->
[同日追記]
Ubuntu 16.04.1にアップグレード後、私の環境では、新たにインストールされた " Ubuntu Software " というソフトウェア管理ツールが起動しないようです。暫く経てばバグの修正が行われるでしょうが、それまでは従来の " Ubuntu ソフトウェア センター " を使用する必要がありそうです。
<-<-

最新版の "YaCy ver. 1.90" は "Java 8" が必要です。 [P2P検索エンジン YaCy]

P2P通信技術を用いた分散型の検索エンジンである " YaCy " のメイン リリースの最新版である、 " YaCy 1.90 " がリリースされました。
この最新版では、今まで公式ウェブサイトで配布されていた " ver. 1.82 " と比較して非常に多くの改良が施されております。
機能の向上と速度の向上が幅広く行われました。

過去に古いヴァージョンを使用して不充分だと感じた方も、最新版ではこれならば利用出来ると感じるかもしれません。

最新版である " ver. 1.90 " は " Java 8 " で動作致しますので、PCに " Oracle JDK 8 " , " Oracle JRE 8 " , " OpenJDK 8 " , " OpenJRE 8 " の何れもインストールされていない場合はこれをインストールします。
因みに、JDK (Java Development Kit)は開発環境込みのもので、JRE (Java Runtime Enviroment)はプログラムの実行のみ可能なものです。

->->
[後日追記]
YaCy ver. 1.90はその後修正され、 " Java 7 " でも動作するようになっております。
<-<-

私はUbuntu PCを利用しておりますので、Oracle Java互換の " OpenJRE 8 " を使用させて頂いております。

Ubuntu 14.04 LTSのメイン リポジトリーは " OpenJRE 7 " までの対応で、 " OpenJRE 8 " はUbuntu 14.10以降でメイン リポジトリーに登録されております。

Ubuntu 14.04で " OpenJRE 8 " をインストールするにはPPAを利用致します。インストールは次の様に行います。

まず、ラウンチャーの " コンピューターとオンラインリソースを検索 " のアプリケーション一覧から " 端末 " を選択するか、或いは " Ctrl + Alt + T " を押して " 端末 " を開きます。
そして次のコマンドを入力致します。
sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-8-jre

管理者パスワードを入力して " Enter キー " を押すとインストールが始まります。
途中で " Do you want to continue? [Y/n] " と出たら、インストールを続けたい場合は " y " と入力して " Enter キー " を押すとインストールが続行されます。もしも中止したい場合は " n " と入力して " Enter キー " を押して下さい。
インストールが終わったら、次のコマンドでOpenJRE 8が正しくインストールされた事を確認します。
java -version


また、Ubuntu 14.04にて古いヴァージョンの " OpenJRE 7 " が既にインストールしてあり、 " OpenJRE 7 " が不要な場合は削除して下さい。
古いヴァージョンも使い続けたい場合は、 " OpenJRE 8 " をインストールした後で、 " 端末 " で次のコマンドを入力して使用するヴァージョンを切り替えて下さい。
sudo update-alternatives --config java

利用可能なヴァージョンが表示されるので、使用したいヴァージョンの番号を入力して " Enter " キーを押します。

参照させて頂いたウェブサイト:
"CUBE SUGAR STORAGE" の記事 "Ubuntu で使用する Java のバージョンを切り替える" のURL:
http://momijiame.tumblr.com/post/70771860020/ubuntu-で使用する-java-のバージョンを切り替える

情報を参照させて頂いた事に心より感謝致しております。

YaCyを利用する事で、国家や企業によるインターネットの検閲、不正、不当なフィルタリングを防ぐ事が可能です。
但し、通信自体を匿名化するものではございませんので、その目的の為には他のシステムを組み合わせる必要がございます。

以下は暫く前のヴァージョンのYaCyのスクリーンショット画像です。
YaCy_SS_(2015_06_25)_1_Edited_1 分散型インターネット検索エンジン "YaCy" のスクリーンショット画像。検索結果の一覧が表示されている。
https://c1.staticflickr.com/1/751/22190971565_8a57afc081_o.png

"YaCy" の公式ウェブサイトのURL:
http://yacy.net/en/index.html

YaCyの導入の仕方やアップデートの仕方等につきましては以前の私の記事を御覧下さい。

[ブログ記事]
分散型検索エンジン "YaCy" が正式に日本語化されました。
http://crater.blog.so-net.ne.jp/2016-02-25

検索エンジン "YaCy" は実用性充分です。
http://crater.blog.so-net.ne.jp/2015-10-15

分散型検索エンジン YaCy の導入解説
http://crater.blog.so-net.ne.jp/2015-07-21

分散型検索エンジン YaCy のアップデート
http://crater.blog.so-net.ne.jp/2015-06-25

分散型検索エンジンYaCyについての解説動画
http://crater.blog.so-net.ne.jp/2015-03-22

Ubuntu PCでYaCy検索エンジンの為のポート開放の設定
http://crater.blog.so-net.ne.jp/2014-11-06


" YaCy " の開発用GitHub ページのURL:
https://github.com/yacy/yacy_search_server

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。