たけぼーの備忘録

暇を持て余した人間の無意味なブログ

FireFoxのJsonビューアーがかなり便利

こんにちは。今日はFireFoxに関する話題です。

最近、といってももう去年の話ですが、FireFoxは新バージョンであるFireFox Quantumを発表し、話題となっています。
Mozillaによると、並列処理が効率的になり、急バージョンよりかなりの高速化に成功したそうで、Chromeよりも速くメモリ消費が少ないとか。

今日の内容とは直接関係はしないのですが、Chrome使いの私としてはQuantumは気になる存在でした。

今まで使ったことはなかったのですが、初めてインストールしました。

確かにメモリ消費は減っている気がします。表示もちょっと早いのかな?

今回はそんなFireFoxJSONビューアーについてです。

FireFoxJSONビューアー

JSONビューアーはその名の通り、JSONを表示するものなのですが、これが使いやすい!

URLにアクセスしてJSONが返されると、自動的にデータを読み込み、見やすく階層表示してくれます。

私は今REST APIを使ったアプリの開発をしているのですが、開発中に偶然FireFoxJSONを取得した際、きれいに整頓されて表示され、驚きました。
ほんとに見やすい!

f:id:takebo_blog:20180116185532j:plain
こんなJSONデータが返されるURLにアクセスしたら

f:id:takebo_blog:20180116185535j:plain
このように、完璧に整理されます!非常に見やすい!
何が返されているのか一目瞭然です。

こういうことをしてくれるソフトは恐らく他にもたくさんあるのだろうけど、ブラウザで読み込むだけで整理されるのは大きいですね。それもプラグイン無しで。

Chromeなんか、読み込んだだけではJSONの整形すらしてくれませんからね。

ということで、今回はFireFoxJSONビューアーについて、でした。
この機能自体は、以前からFireFoxに搭載されていたようですので、知っている方には、何を今更言ってるんだ、という記事になったと思います。ご勘弁ください。

非常に便利ですので、皆さんも使ってみてくださいね。

ではまた。

スマホ選びで後悔しないために見ておくポイントを書き出してみる

Android robot toy
こんにちは。
今回は、スマホに関する話題です。

前振り

つい最近、本格的な冬が到来しました。というとこは、次は春がきますね。ということは、機種変更の時期がやってきますね(笑)

かなり強引かもしれませんが、私は2年前の3月に機種変更しましたので、ついに2年縛りが解ける時期な訳です。3月は値引き合戦となるため、3月に契約した方も多いのではないでしょうか。

現在、Xperia Z5を使用しています。auで契約し、キャンペーンをこねくり回して加入したので、月々なんと3500円!

格安SIMもびっくりな安さです。

しかし、これは所謂MNPしたら一括0円!があった時代だからできたことで、今はさすがに厳しい状態です。

ということで、次の機種変更と共に格安SIMに乗り換えることを決意したのですが、なにせ種類が多い

格安SIMの話はまた今度まとめようかと思うのですが、今回はスマホについてです。

格安SIMにするなら、スマホはどれでもいいわけです。
主要3キャリアで売っているスマホ以外にも、この世にはたくさんのスマホがあります。

私は調べていて思いました。
どれがいいのかわからない!!と。
何を基準に選べばいいのか分からない!!と。

ということで、今回はそんな沢山のスマホから何を基準に選べばいいのか考えてみます。

よく知られているメーカー

HTC Android phone launch-20
格安SIMとセットで売られているスマホの中には、あまり聞き慣れない(でもその界隈ではかなり有名な)メーカーが沢山あります。

ということで、まずはそちらの説明から。

Sony

Xperiaシリーズを提供するソニー。特徴は何といってもカメラ音質です。
カメラ内のセンサーではトップクラスソニーは、搭載のカメラ性能が高いです。
また、Walkmanで培った音声処理技術で、どんなイヤホンでも素晴らしいクリアな音声が出ます。本体内蔵のスピーカー性能も高いです。

シャープ

鴻海に吸収されたことで有名なシャープ。AQUOSシリーズを提供します。
鴻海に吸収されてから、シャープは丸くなった?気がします。以前は、AndroidのOSアップデートは絶対に提供しないことで有名で、rootを取りにくいようなシステム改良が行われていたりと、堅いイメージだったのですが、最近は2年間のOSバージョンアップを確約するなど、新たな動きを見せています。
液晶画面に搭載されているIGZOは、省電力性能がかなり高いことが特徴で、このIGZOのおかげで鴻海に救われたとかそうでなかったとか。

FUJITSU

PC部門で有名な富士通。ARROWSシリーズを提供しています。
初期の頃は、ガラケーにあった機能をすべて詰め込みすぎて、発熱がひどく、巷ではカイロとしか使えないなんて言われる始末となりました。
しかし、今では安定した性能のスマホを提供し、日本独自の機能であるワンセグおサイフケータイを搭載している、なんとも日本向けなスマホを作っています。

京セラ

京セラは、主要3キャリアでも安い部類のスマホとしてよく登場します。
ガラケーの延長のようなスマホも多く、ガラケーユーザーには使いやすいように思います。
まだガラケーを製造している数少ないメーカーであることも関係あるかもしれません。

Samsung

サムスンは、GALAXYシリーズを提供する韓国メーカーです。
Galaxyシリーズといえば、バッテリー発火で一時期お茶の間を賑わせ、大量のリコールとなり、機内持ち込みが禁止になったり、挙げ句の果てには戦闘ゲームの武器としてGalaxyを使うというMODが出たりと、大騒ぎになりました。
しかし、現在ではそんな心配はなく、かなりの高性能スマホを提供し、シェアは世界一です。

LG

テレビ部門で日本でも有名なLGは、auのisaiなどを提供する韓国メーカーです。
音質や画面の美しさにこだわった端末が打ち出されており、ガラケースマホを掛け合わせたガラホを売り出したりしています。

HTC

htcは主にスマートフォンを製造する台湾メーカーです。
国内メーカーに比べて、低価格で高性能スマホが製造されています。
海外メーカーでは珍しく、おサイフケータイなどの日本特有の機能を持ったスマホが発売されていたりします。

ASUS

ASUSは台湾に本社を置くメーカーで、PCの製造でも有名です。
ZenFoneシリーズを販売しており、主要3キャリアではあまり見ませんが、低価格で性能の良いスマホとして世界的にも有名です。
ZenFoneシリーズは、ライトユーザー向けの低価格モデルからヘビーユーザー向けのハイスペックモデルまで様々な種類があります。名前が似ていても、スペックがまるっきり違ったりします。

HUAWEI

HUAWEIはPシリーズやMateシリーズなど様々なスマホを製造する中国メーカーです。
HUAWEI製のスマホは、HUAWEI独自に開発したSoC(CPUやGPUなどの複合体)を採用した端末が多く、低価格のスマホの中でも、かなり性能の高いのが特徴です。
またカメラに力を入れており、Leica監修のカメラを搭載したものもあります。
世界シェアも3位とかなりの売れ行きで、主要3キャリアではあまり見ませんが、格安SIMとのセットでは必ず選択肢の中に入っていると思います。

メーカーのまとめ

よく知られているメーカーはこんなところでしょうか。他にもメーカーは沢山あります。

私はソニー・シャープ・富士通スマホを持っていたことがあります。説明になんとなく感情がこもりすぎたかもしれません。特に富士通には…
海外メーカーは使ったことがないので、私が知る限り精一杯の知識で書きましたが、間違ってたら教えてください。

スペックを評価するポイント

メーカーの紹介が終わったところで、今度はスマホを買うときにどこを見比べたらいいのか、について話を移しましょう。

ポイントごとに書きますが、かなりマニアックな内容も含まれているかもしれませんので、困ったらスルーしてください。

SoC

CPUs
SoCはCPUやGPUなどをまとめたものです。ですので、スマホの処理能力を決める最も大事な部品です。
性能評価ではよくSoCが評価されます。

SoCを評価する上で、見なければならないのは、SoC名クロック周波数コア数ベンチマークです。

特に、ベンチマークはかなり役に立ちますので、覚えておきましょう。

ベンチマークとは、SoCの性能を数値化したもので、概ね数値が大きければ大きいほどよいです。

ベンチマークは様々な方法で行われていますが、有名なのはAntutuによるベンチマークです。
Antutuによるベンチマークの数字は、5000程度の差なら無視しても良いですが、やはり10000ほど違うと体感として大きく異なると言われています。

こちらに、ベンチマークの値が一覧で掲載されていますので、参考にしましょう。

クロック周波数とコア数はCPUに関係する数字です。
SoC内のCPUは処理全般を担当する部分です。
CPUはクロック周波数とコア数が性能に大きく影響し、一概には言えませんが、それぞれ数字が大きい方が性能が高い傾向にあります。
しかし、コア数が多いからといって高性能という訳ではなく、あくまで一つの指針としてとらえてください。

SoC名はQualcomm製のSnapdragonや、Mediatek製のもの、HiSilicon製のKirinサムスン製のExynosなどがあります。
他にも、PCではトップメーカーのIntel製のAtomというものがありますが、スマホではほとんど使用されていません。と言うよりも、Snapdragonが使われているものがほとんどです。

Snapdragon

Snapdragonは200シリーズ400シリーズ600シリーズ800シリーズの4種類があります。

  1. 200シリーズ
    ほぼ使われているものを見たことがありません。国内では簡単スマホなどに使われています。
    このシリーズは、いわゆるローエンドモデルで、性能の低いものとなります。
    あまり手を出さない方が身のためです。
  2. 400シリーズ
    エントリークラスのSoCで、安価なスマホに搭載されることが多いです。最近は8コアのものもありますが、クロック周波数は低く、安さを重視したモデルとなっています。
    このシリーズは、LINEやFacebookなどの使用がメインで、ゲームはあまりしない方は満足できる性能があります。
  3. 600シリーズ
    ミッドレンジクラスのSoCで、グラフィック性能はあまり高くありませんが、処理能力は高めのモデルです。
    最近では8コアのものが主流で、格安スマホの中でも値段が高い部類に搭載されることが多いです。
    もっとも新しいSnapdragon 660は、ハイエンドモデルのSnapdragon 810よりベンチマークが高く、600シリーズでも性能がかなりよいものが登場しています。
  4. 800シリーズ
    ハイエンドクラスのSoCで、各メーカーでもっとも性能の高いスマホはほぼこのシリーズが搭載されています。
    処理能力の高さはもちろんですが、グラフィック性能も高いので、3Dのゲームをやってももたつくことがありません。
    その分値段はお高いです。

Mediatek

MediatekはSnapdragonよりも低価格なモデルを販売していますが、性能はSnapdragonよりも劣っているものが多いです。
Snapdragon 200シリーズのものを選ぶぐらいならMediatekのものがいいですが、あえてMediatek搭載のものを選ぶ必要はないと思います。
安さ重視なら選択肢の一つとなるでしょう。
Helioシリーズというのがあり、こちらはやや性能が高いです。

Kirin

KirinはHUAWEI製のスマホに搭載されているSoCです。これを製造するHiSiliconはHUAWEIの子会社なので、HUAWEIスマホは製造コストが低く、低価格なのに高性能なSoCが多いです。
ですので、同様の価格帯のスマホの中でHUAWEI製のスマホは、やや性能が高いこともしばしばです。
Kirinはモデルによって性能が大きく違うため、ベンチマークを参考にしましょう。

Exynos

Exynosはサムスン製のスマホに搭載されるSoCです。しかし、すべてのサムスン製品に搭載されるわけではなく、比較的価格が控えめなスマホに搭載されるようです。

SoCのまとめ

結論をまとめておきましょう。長々と書いてきましたが、

  • SoCは名前クロック周波数コア数を参考にする
  • 性能評価はベンチマークが分かりやすい
  • 3DゲームをしないならSnapdragon 400シリーズでもやっていける
  • 3Dゲームをするなら、Snapdragon 800シリーズがベスト。600シリーズでもやっていける
  • Kirinはモデルごとに性能が違うから注意
  • MediatekとExynosはとりあえず置いておこう

といったところです。

対応周波数

tesco phone shop
日本では、docomoauSoftBankの3社がLTE回線を運営しており、格安SIMはこれらの会社から回線を借りて運営しています。
詳しくは書きませんが、格安SIMほとんどがdocomoで、mineoやUQmobileがau系、Y!mobileソフトバンク系です。

格安SIMスマホを使うときは、使う回線の周波数に対応しているかがポイントとなります。

特にauの周波数は特殊であるため、注意が必要です。

本来は4GLTEで契約していても、音声通話は3G回線で行うのが通常です。
しかし、最近では音声通話も4GLTEで行うVoLTEという技術が用いられるようになってきました。
つまり、音声通話をする際には、VoLTEに対応しているか、3G回線に対応しているかのどちらかが必要です。

auの3G回線世界的にも特殊なCDMA2000方式を使用しており、docomoSoftBankとは全く異なります。
そのため、auの3G回線に対応しているものはかなり少ないのが現状です。
また、VoLTEに対応しているかもバラバラのため、au回線で使えるスマホは数が限られています

au回線を使う予定の方は、ここに注意しなければなりません。

LTEや3Gなどは、Bandという数字で分けられており、

となっています。
3社ともBand 1を使っています。Band 1は海外でも広く使われているため、ほとんどのスマホがこれに対応しています。
不思議なのが、実はBand 26はBand 18としても活躍するので、Band 26に対応していれば、Band 18対応でなくても良いのです。

docomoでは、Band 1をメインとして運用しています。また東名阪ではBand 3にて速度を向上させています。Band 19はプラチナバンドと呼ばれ、電波につながりやすくしています。
docomoの場合、Band 1/3/19に対応していることが望ましいです。

auBand 18がメインです。Band 1も広く使われていますが、それだけでは不安定な場所もあるとか。
auの場合、Band 18(もしくは26)に対応していることが必要です。

SoftBankBand 1と8がメインのため、こちらに対応しなければなりません。

実際のところ、日本国内で売られているスマホなら、ほとんどがdocomoに対応しています。

周波数のまとめ

スマホを買うときには、対応Bandを調べてから買いましょう。

格安SIMでも速度が速いau格安SIMを使うなら、対応BandとauのVoLTE対応かを必ず確認しましょう。
auの3G回線に対応したものは本当に少ないので注意してください。

docomo系を使う方は、あまり深く気にしなくても大丈夫です。

メモリ

Memory
メモリは、CPUで処理するためにデータを一次的に置いておく場所で、4GBが主流です。
メモリは大きければ大きいほど良いです。

DSDS

SIM Card.
DSDSとは、スマホSIMカードを2枚搭載できる機能です。これは主要3キャリアで販売されるスマホにはない機能ですが、SIMを2枚指すことができると、2回線を同じスマホで使い分けることができます。

バッテリー

Connexion 48/52
バッテリーの容量は、mAhの値で表記されています。標準的なスマホでは、2500~3000mAhのバッテリーが搭載されています。

また、最近では急速充電の機能が搭載されたものがあり、短時間で充電ができるものがあります。

カメラ

Google Pixel XL smartphone
カメラの性能は皆さんもかなり重視するポイントではないでしょうか。
カメラの性能は、素数で評価されます。一般に画素数が高ければ、鮮明な写真が撮れます。

しかし、画素数の高さと実際の美しさは必ずしもイコールとはいえません

カメラセンサーから入った情報をうまく処理できるか、によって美しさが大きく変わります。

また、最近ではレンズを二つ搭載するモデルも現れ、スマホのカメラは混沌とした世界になっています。

このあたりは、「機種名 カメラ」で検索すると実際に撮影してみた方のレビューが見れたりします。

また、SoCのAntutuベンチマークのように、カメラの性能を数値化したものもあります。
それが、DxOMarkです。
https://www.dxomark.com/category/mobile-reviews/

これを書いている12月現在では、Pixel 2がiPhoneを抜いてトップのようです。

NFC

NFC stickers, wristband & key fob to experiment with!
NFCとは、おサイフケータイのようにタッチで何かを行う機能のことですが、おサイフケータイとは別物ですので注意が必要です。

音響

Lr43_L1000321
本体内蔵のスピーカーにはモノラルステレオの2タイプあります。
当然ですが、ステレオの方が音がよいです。
また、イヤホンに出力される音声は、各社がそれぞれカスタマイズしている部分なので、一概にどれが良いとは言えません。

個人的には、Sonyの音声は本当に良いと思いますが、これは好みの問題ですね。

総括

ここまでかなり長くなりましたが、いかがでしょうか。

今まで書いたものすべてをみる必要はないと思います。
周波数は必ず確認しなければなりませんが、その他は一番重視するものを詳しく調べると良いでしょう。

たとえば、写真をよく撮るならカメラの性能を、ゲームをよくやるならSoCの性能を入念に調べると、後から後悔せずに済みます。

本当にたくさんの種類があるスマートフォン。皆さんも自分にぴったりの一台を見つけてください。

ではまた。

家のルーターをNECのWG1200HP2に変えてみた

こんにちは。
今日はいつもとはジャンルの違う話を。

ルーターを交換する機会があったので、書いてみます。

交換前のルーター

2年前にスマホを新調したときに、セットで買ったこちらのルーター
Buffalo製で5GHz・2.4GHzどちらも対応した普及モデルと言ったところです。

BUFFALO【iphone6 対応】11ac/n/a/b/g 無線LAN親機(Wi-Fiルーター)エアステーション Giga ビームフォーミング対応 866+300Mbps WSR-1166DHP2/N (利用推奨環境4人・3LDK・2階建て) [フラストレーションフリーパッケージ(FFP)]

2年間頑張って使いましたが、正直にいうと動作が不安定。2.4GHzの方が現れなくなる、なんていう時があったりして、なんとも怪しい動きをしました。

恐らく、私のものは不良品だったのだろうけど、使えないわけでもないし、修理代かかるし…

ということで、2年使い続けてきました。

しかし、またまたスマホを新調しましたので、ついでにということで新しくしました。

個人的には、不安定な動作よりも自分の部屋まで無線の電波が届かないことの方が不満でした。

これは、私の家の作りとルーターの位置が問題ですが。

交換後のルーター

タイトルにもある通り、NECのWG1200HP2に買い換えました。

NEC Aterm WG1200HP 11ac/n/a(5GHz帯)&11n/g/b(2.4GHz帯) 無線LAN親機(Wi-Fiルーター) 同時利用タイプ 867+300Mbps PA-WG1200HP

2ストリームで2.4GHzと5GHzの両方に対応しています。
さらに、ビームフォーミングやMU-MIMOなどの最新(?)機能もちらほら兼ね備えています。

期待できるのは、電波強度が前のものに比べ強くなっていることです。

また、CPUがデュアルコアで処理能力が高いことも期待できそう。

使用感

ちゃんとつながります。当たり前ですけど。

初期設定がかなり簡単で、ネットワークへの接続も1分程度で終わりました。

また、スマホへのWi-Fi設定もNFCでタッチするだけ、という簡単さ。
これには驚きました。

通信状態は良好で、やや通信速度も上がった気がする?
これは恐らく気のせいです。

少し困るのは、スマホWi-Fiへ接続したとき、ちゃんとつながるまでの時間がやや長いことです。
これは恐らく気のせいではありません。

最後に

まだ使い始めたばかりなので、ここに書いたのは使い始めた感想です。
あまり参考にならないかと思います。

もう少し使ったらさらに書き足そうかと思います。

ではまた。

KygoのKids in Loveを和訳してみる

こんにちは。

今日はお気に入りの曲を紹介します。
それは、KygoのKids in Loveです。

この曲のタイトルとなっているKids in Loveという言葉は、曲中にもたくさん出てきます。
直訳すると、恋に落ちた子ども達、といったところです。

Kygoによると、Kids in Loveとは誰かや何かに夢中になっていることを指しているそうです。

それでは、和訳してみましょう。

Kids in Love

This is our last goodbye

これが最後のさよならだよ

Don't come and find me

僕を探しにこないでね

So hard to see you cry

君が泣くのを見るのはとても辛いんだ

Please, somebody blind me

お願いだから、誰か僕を見えなくしてくれ

Cause I can feel it

なぜなら、僕は感じられるんだよ

I'm still lagging onto every word

未だに僕はすべての言葉に捕らわれているよ

My heart is beating

僕の心はドキドキしてるよ

And I'm sorry that I left you hurt

そして僕は君を傷つけたまま去ったことを悪く思ってる

We were kids in love

僕らは夢中で恋してたんだ

And then we grew up

そして僕らは成長した

But won't you hold me close tonight

でも今夜は近くに引き留めないんだろう

Like we're kids in love

恋に落ちた子どものように

Kids in love
Kids in love
Kids in love

夢中で恋してたんだ

We were kids in love
We were kids in love

僕らは恋に落ちた子供だったね

Engine on, in the drive

エンジンをかけてドライブする

Running for hours

何時間もかけて走ってる

Slowly, we twist the knife

ゆっくり古傷にふれて

We're falling like towers

タワーのように崩れてしまったんだ

And I can feel it

僕は感じられるんだ

And we're running out of hope tonight

そして今夜望みはなくなってしまった

I hear you breathing

君が息を吸うのが聞こえる

As we're hanging on to you and I

君と僕が互いにしがみついてるように

We were kids in love

僕らは夢中で恋してたんだ

And then we grew up

そして僕らは成長した

But won't you hold me close tonight

でも今夜は近くに引き留めないんだろう

Like we're kids in love

恋に落ちた子どものように

Kids in love
Kids in love
Kids in love

夢中で恋してたんだ

Maybe I could cope if I could hold you

もし君を引き留めることができたなら、もしかしたら僕はうまくやれてたかもしれない

We were kids in love

僕らは夢中で恋してたんだ

One last time, one last time

もう一度だけ、もう一度だけ

And I'll never let go, I'll just hold you forever

そしたら二度と行かせず、永遠に君を引き留めておくよ

Maybe I could cope if I could hold you

もし君を引き留めることができたなら、もしかしたら僕はうまくやれてたかもしれない

We were kids in love

僕らは恋に落ちた子供だったんだ

Kids in love
Kids in love
Kids in love

夢中で恋してたんだ

所感

歌詞の内容はちょっと切ない気がします。サビのメロディーは開放的な音で、すっきりとしたイメージで、個人的に好きです。

是非聞いてみてください。ではまた。

Kids in Love

Kids in Love (feat. The Night Game)

Kids in Love (feat. The Night Game)

  • Kygo
  • ダンス
  • ¥250

大浦版FFTをJavaに移植する

f:id:takebo_blog:20171019164554j:plain
今回は、高速な処理で有名な大浦版FFTJavaに移植してみました。

大浦版FFTとは、Cで書かれた高速フーリエ変換(FFT)で、1次元・2次元・3次元のバージョンがあります。
FFT Package 1-dim / 2-dim

ググってみると、Java移植の話題はちょくちょくあるのですが、ソースコードが載っているものが少ないので、書いてみました。

正直言いますと、こちらのソースをかなり参考にさせていただいております。
要するに、配列をずらしたりする処理を書き換えればいいのです。
大浦版FFTのJava移植

移植での変更点

Javaではポインタが使えないため、配列をそのまま引数として渡さなければなりません。

また、配列をずらす、という動作を行うための処理部分を変更しなければなりません。
Cでは例えば、配列 a [ n ] があったなら、a+2で配列aを2つずらすことができ、これをそのまま関数へ渡すことができます。しかし、Javaにはそのような機能はなく、配列を2つずらすなら、a [ n + 2 ]と書かなければなりません。
この二つの違いを直すと、正常に動くようになります。

今回移植したのは、FFT4gだけです。手抜きですいません。
間違ってたらごめんなさい。勘弁してください。
ということで、ソースコード全体はこちら。

FFT4g.java

package …;

import static java.lang.Math.atan;
import static java.lang.Math.cos;
import static java.lang.Math.sin;

public class FFT4g {
    private int[] ip;
    private double[] w;
    private int n;
    private double t[];

    FFT4g(int n) {
        this.n = n;
        ip = new int[2+(int)Math.sqrt((double)n/2.0)+1];
        w = new double[n*5/4];
        t = new double[n/2];

        ip[0] = 0;
    }

    public void cdft(int isgn, double[] a)
    {
        if (n > (ip[0] << 2)) {
            makewt(n >> 2);
        }
        if (n > 4) {
            if (isgn >= 0) {
                bitrv2(n, a);
                cftfsub(n, a);
            } else {
                bitrv2conj(n, a);
                cftbsub(n, a);
            }
        } else if (n == 4) {
            cftfsub(n, a);
        }
    }

    public void rdft(int isgn, double[] a) {
        int nw, nc;
        double xi;

        nw = ip[0];
        if (n > (nw << 2)) {
            nw = n >> 2;
            makewt(nw);
        }
        nc = ip[1];
        if (n > (nc << 2)) {
            nc = n >> 2;
            makect(nc,w, nw);
        }
        if (isgn >= 0) {
            if (n > 4) {
                bitrv2(n, a);
                cftfsub(n, a);
                rftfsub(n, a, nc, w, nw);
            } else if (n == 4) {
                cftfsub(n, a);
            }
                xi = a[0] - a[1];
                a[0] += a[1];
                a[1] = xi;
        } else {
            a[1] = 0.5 * (a[0] - a[1]);
            a[0] -= a[1];
            if (n > 4) {
                rftbsub(n, a, nc, w, nw);
                bitrv2(n, a);
                cftbsub(n, a);
            } else if (n == 4) {
                cftfsub(n, a);
            }
        }
    }


     public void ddct(int isgn, double[] a){
            int j, nw, nc;
            double xr;

            nw = ip[0];
            if (n > (nw << 2)) {
                nw = n >> 2;
                makewt(nw);
            }
            nc = ip[1];
            if (n > nc) {
                nc = n;
                makect(nc, w, nw);
                }
            if (isgn < 0) {
                xr = a[n - 1];
                for (j = n - 2; j >= 2; j -= 2) {
                    a[j + 1] = a[j] - a[j - 1];
                    a[j] += a[j - 1];
                }
                a[1] = a[0] - xr;
                a[0] += xr;
            if (n > 4) {
                rftbsub(n, a, nc, w, nw);
                bitrv2(n, a);
                cftbsub(n, a);
            } else if (n == 4) {
                cftfsub(n, a);
            }
        }
        dctsub(n, a, nc, w, nw);
        if (isgn >= 0) {
            if (n > 4) {
                bitrv2(n, a);
                cftfsub(n, a);
                rftfsub(n, a, nc, w, nw);
            } else if (n == 4) {
                cftfsub(n, a);
            }
            xr = a[0] - a[1];
            a[0] += a[1];
            for (j = 2; j < n; j += 2) {
            a[j - 1] = a[j] - a[j + 1];
            a[j] += a[j + 1];
            }
            a[n - 1] = xr;
        }
    }

    public void ddst(int isgn, double[] a)
    {
        int j, nw, nc;
        double xr;

        nw = ip[0];
        if (n > (nw << 2)) {
            nw = n >> 2;
            makewt(nw);
        }
        nc = ip[1];
        if (n > nc) {
            nc = n;
            makect(nc, w, nw);
        }
        if (isgn < 0) {
            xr = a[n - 1];
            for (j = n - 2; j >= 2; j -= 2) {
                a[j + 1] = -a[j] - a[j - 1];
                a[j] -= a[j - 1];
            }
            a[1] = a[0] + xr;
            a[0] -= xr;
            if (n > 4) {
                rftbsub(n, a, nc, w, nw);
                bitrv2(n, a);
                cftbsub(n, a);
            } else if (n == 4) {
                cftfsub(n, a);
            }
        }
        dstsub(n, a, nc, w, nw);
        if (isgn >= 0) {
            if (n > 4) {
                bitrv2(n, a);
                cftfsub(n, a);
                rftfsub(n, a, nc, w, nw);
            } else if (n == 4) {
                cftfsub(n, a);
            }
            xr = a[0] - a[1];
            a[0] += a[1];
            for (j = 2; j < n; j += 2) {
                a[j - 1] = -a[j] - a[j + 1];
                a[j] -= a[j + 1];
            }
            a[n - 1] = -xr;
        }
    }

    public void dfct(double[] a)
    {
        int j, k, l, m, mh, nw, nc;
        double xr, xi, yr, yi;

        nw = ip[0];
        if (n > (nw << 3)) {
            nw = n >> 3;
            makewt(nw);
        }
        nc = ip[1];
        if (n > (nc << 1)) {
            nc = n >> 1;
            makect(nc, w, nw);
        }
        m = n >> 1;
        yi = a[m];
        xi = a[0] + a[n];
        a[0] -= a[n];
        t[0] = xi - yi;
        t[m] = xi + yi;
        if (n > 2) {
            mh = m >> 1;
            for (j = 1; j < mh; j++) {
                k = m - j;
                xr = a[j] - a[n - j];
                xi = a[j] + a[n - j];
                yr = a[k] - a[n - k];
                yi = a[k] + a[n - k];
                a[j] = xr;
                a[k] = yr;
                t[j] = xi - yi;
                t[k] = xi + yi;
            }
            t[mh] = a[mh] + a[n - mh];
            a[mh] -= a[n - mh];
            dctsub(m, a, nc, w, nw);
            if (m > 4) {
                bitrv2(m, a);
                cftfsub(m, a);
                rftfsub(m, a, nc, w, nw);
            } else if (m == 4) {
                cftfsub(m, a);
            }
            a[n - 1] = a[0] - a[1];
            a[1] = a[0] + a[1];
            for (j = m - 2; j >= 2; j -= 2) {
                a[2 * j + 1] = a[j] + a[j + 1];
                a[2 * j - 1] = a[j] - a[j + 1];
            }
            l = 2;
            m = mh;
            while (m >= 2) {
                dctsub(m, t, nc, w, nw);
                if (m > 4) {
                    bitrv2(m, t);
                    cftfsub(m, t);
                    rftfsub(m, t, nc, w, nw);
                } else if (m == 4) {
                    cftfsub(m, t);
                }
                a[n - l] = t[0] - t[1];
                a[l] = t[0] + t[1];
                k = 0;
                for (j = 2; j < m; j += 2) {
                    k += l << 2;
                    a[k - l] = t[j] - t[j + 1];
                    a[k + l] = t[j] + t[j + 1];
                }
                l <<= 1;
                mh = m >> 1;
                for (j = 0; j < mh; j++) {
                    k = m - j;
                    t[j] = t[m + k] - t[m + j];
                    t[k] = t[m + k] + t[m + j];
                }
                t[mh] = t[m + mh];
                m = mh;
            }
            a[l] = t[0];
            a[n] = t[2] - t[1];
            a[0] = t[2] + t[1];
        } else {
            a[1] = a[0];
            a[2] = t[0];
            a[0] = t[1];
        }
    }

    public void dfst(double[] a)
    {
        int j, k, l, m, mh, nw, nc;
        double xr, xi, yr, yi;

        nw = ip[0];
        if (n > (nw << 3)) {
            nw = n >> 3;
                makewt(nw);
        }
        nc = ip[1];
        if (n > (nc << 1)) {
            nc = n >> 1;
            makect(nc, w, nw);
        }
        if (n > 2) {
                m = n >> 1;
                mh = m >> 1;
            for (j = 1; j < mh; j++) {
                k = m - j;
                xr = a[j] + a[n - j];
                xi = a[j] - a[n - j];
                yr = a[k] + a[n - k];
                yi = a[k] - a[n - k];
                a[j] = xr;
                a[k] = yr;
                t[j] = xi + yi;
                t[k] = xi - yi;
            }
            t[0] = a[mh] - a[n - mh];
            a[mh] += a[n - mh];
            a[0] = a[m];
            dstsub(m, a, nc, w, nw);
            if (m > 4) {
                bitrv2(m, a);
                cftfsub(m, a);
                rftfsub(m, a, nc, w, nw);
            } else if (m == 4) {
                cftfsub(m, a);
            }
            a[n - 1] = a[1] - a[0];
            a[1] = a[0] + a[1];
            for (j = m - 2; j >= 2; j -= 2) {
                a[2 * j + 1] = a[j] - a[j + 1];
                a[2 * j - 1] = -a[j] - a[j + 1];
            }
            l = 2;
            m = mh;
            while (m >= 2) {
                dstsub(m, t, nc, w, nw);
                if (m > 4) {
                    bitrv2(m, t);
                    cftfsub(m, t);
                    rftfsub(m, t, nc, w, nw);
                } else if (m == 4) {
                    cftfsub(m, t);
                }
                a[n - l] = t[1] - t[0];
                a[l] = t[0] + t[1];
                k = 0;
                for (j = 2; j < m; j += 2) {
                    k += l << 2;
                    a[k - l] = -t[j] - t[j + 1];
                    a[k + l] = t[j] - t[j + 1];
                }
                l <<= 1;
                mh = m >> 1;
                for (j = 1; j < mh; j++) {
                    k = m - j;
                    t[j] = t[m + k] + t[m + j];
                    t[k] = t[m + k] - t[m + j];
                }
                t[0] = t[m + mh];
                m = mh;
            }
            a[l] = t[0];
        }
        a[0] = 0;
    }

/* -------- initializing routines -------- */

    private void makewt(int nw)
    {
        int j, nwh;
        double delta, x, y;

        ip[0] = nw;
        ip[1] = 1;
        if (nw > 2) {
            nwh = nw >> 1;
            delta = atan(1.0) / nwh;
            w[0] = 1;
            w[1] = 0;
            w[nwh] = cos(delta * nwh);
            w[nwh + 1] = w[nwh];
            if (nwh > 2) {
                for (j = 2; j < nwh; j += 2) {
                    x = cos(delta * j);
                    y = sin(delta * j);
                    w[j] = x;
                    w[j + 1] = y;
                    w[nw - j] = y;
                    w[nw - j + 1] = x;
                }
                bitrv2(nw, w);
            }
        }
    }


    private void makect(int nc, double[] c, int nw)
    {
        int j, nch;
        double delta;

        ip[1] = nc;
        if (nc > 1) {
            nch = nc >> 1;
            delta = atan(1.0) / nch;
            c[nw + 0] = cos(delta * nch);
            c[nw + nch] = 0.5 * c[0];
            for (j = 1; j < nch; j++) {
                c[nw + j] = 0.5 * cos(delta * j);
                c[nw + nc - j] = 0.5 * sin(delta * j);
            }
        }
    }

/* -------- child routines -------- */

    private void bitrv2(int n, double[] a)
    {
        int j, j1, k, k1, l, m, m2;
        double xr, xi, yr, yi;

        ip[2 + 0] = 0;
        l = n;
        m = 1;
        while ((m << 3) < l) {
            l >>= 1;
            for (j = 0; j < m; j++) {
                ip[2 + m + j] = ip[2 + j] + l;
            }
            m <<= 1;
        }
        m2 = 2 * m;
        if ((m << 3) == l) {
            for (k = 0; k < m; k++) {
                for (j = 0; j < k; j++) {
                    j1 = 2 * j + ip[2 + k];
                    k1 = 2 * k + ip[2 + j];
                    xr = a[j1];
                    xi = a[j1 + 1];
                    yr = a[k1];
                    yi = a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                    j1 += m2;
                    k1 += 2 * m2;
                    xr = a[j1];
                    xi = a[j1 + 1];
                    yr = a[k1];
                    yi = a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                    j1 += m2;
                    k1 -= m2;
                    xr = a[j1];
                    xi = a[j1 + 1];
                    yr = a[k1];
                    yi = a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                    j1 += m2;
                    k1 += 2 * m2;
                    xr = a[j1];
                    xi = a[j1 + 1];
                    yr = a[k1];
                    yi = a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                }
                j1 = 2 * k + m2 + ip[2 + k];
                k1 = j1 + m2;
                xr = a[j1];
                xi = a[j1 + 1];
                yr = a[k1];
                yi = a[k1 + 1];
                a[j1] = yr;
                a[j1 + 1] = yi;
                a[k1] = xr;
                a[k1 + 1] = xi;
            }
        } else {
            for (k = 1; k < m; k++) {
                for (j = 0; j < k; j++) {
                    j1 = 2 * j + ip[2 + k];
                    k1 = 2 * k + ip[2 + j];
                    xr = a[j1];
                    xi = a[j1 + 1];
                    yr = a[k1];
                    yi = a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                    j1 += m2;
                    k1 += m2;
                    xr = a[j1];
                    xi = a[j1 + 1];
                    yr = a[k1];
                    yi = a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                }
            }
        }
    }

    private void bitrv2conj(int n, double[] a)
    {
        int j, j1, k, k1, l, m, m2;
        double xr, xi, yr, yi;

        ip[2 + 0] = 0;
        l = n;
        m = 1;
        while ((m << 3) < l) {
            l >>= 1;
            for (j = 0; j < m; j++) {
                ip[2 + m + j] = ip[2 + j] + l;
            }
            m <<= 1;
        }
        m2 = 2 * m;
        if ((m << 3) == l) {
            for (k = 0; k < m; k++) {
                for (j = 0; j < k; j++) {
                    j1 = 2 * j + ip[2 + k];
                    k1 = 2 * k + ip[2 + j];
                    xr = a[j1];
                    xi = -a[j1 + 1];
                    yr = a[k1];
                    yi = -a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                    j1 += m2;
                    k1 += 2 * m2;
                    xr = a[j1];
                    xi = -a[j1 + 1];
                    yr = a[k1];
                    yi = -a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                    j1 += m2;
                    k1 -= m2;
                    xr = a[j1];
                    xi = -a[j1 + 1];
                    yr = a[k1];
                    yi = -a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                    j1 += m2;
                    k1 += 2 * m2;
                    xr = a[j1];
                    xi = -a[j1 + 1];
                    yr = a[k1];
                    yi = -a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                }
                k1 = 2 * k + ip[2 + k];
                a[k1 + 1] = -a[k1 + 1];
                j1 = k1 + m2;
                k1 = j1 + m2;
                xr = a[j1];
                xi = -a[j1 + 1];
                yr = a[k1];
                yi = -a[k1 + 1];
                a[j1] = yr;
                a[j1 + 1] = yi;
                a[k1] = xr;
                a[k1 + 1] = xi;
                k1 += m2;
                a[k1 + 1] = -a[k1 + 1];
            }
        } else {
            a[1] = -a[1];
            a[m2 + 1] = -a[m2 + 1];
            for (k = 1; k < m; k++) {
                for (j = 0; j < k; j++) {
                    j1 = 2 * j + ip[2 + k];
                    k1 = 2 * k + ip[2 + j];
                    xr = a[j1];
                    xi = -a[j1 + 1];
                    yr = a[k1];
                    yi = -a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                    j1 += m2;
                    k1 += m2;
                    xr = a[j1];
                    xi = -a[j1 + 1];
                    yr = a[k1];
                    yi = -a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                }
                k1 = 2 * k + ip[2 + k];
                a[k1 + 1] = -a[k1 + 1];
                a[k1 + m2 + 1] = -a[k1 + m2 + 1];
            }
        }
    }

    private void cftfsub(int n, double[] a)
    {
        int j, j1, j2, j3, l;
        double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;

        l = 2;
        if (n > 8) {
            cft1st(a);
            l = 8;
            while ((l << 2) < n) {
                cftmdl(l, a);
                l <<= 2;
            }
        }
        if ((l << 2) == n) {
            for (j = 0; j < l; j += 2) {
                j1 = j + l;
                j2 = j1 + l;
                j3 = j2 + l;
                x0r = a[j] + a[j1];
                x0i = a[j + 1] + a[j1 + 1];
                x1r = a[j] - a[j1];
                x1i = a[j + 1] - a[j1 + 1];
                x2r = a[j2] + a[j3];
                x2i = a[j2 + 1] + a[j3 + 1];
                x3r = a[j2] - a[j3];
                x3i = a[j2 + 1] - a[j3 + 1];
                a[j] = x0r + x2r;
                a[j + 1] = x0i + x2i;
                a[j2] = x0r - x2r;
                a[j2 + 1] = x0i - x2i;
                a[j1] = x1r - x3i;
                a[j1 + 1] = x1i + x3r;
                a[j3] = x1r + x3i;
                a[j3 + 1] = x1i - x3r;
            }
        } else {
            for (j = 0; j < l; j += 2) {
                j1 = j + l;
                x0r = a[j] - a[j1];
                x0i = a[j + 1] - a[j1 + 1];
                a[j] += a[j1];
                a[j + 1] += a[j1 + 1];
                a[j1] = x0r;
                a[j1 + 1] = x0i;
            }
        }
    }

    private void cftbsub(int n, double[] a)
    {
        int j, j1, j2, j3, l;
        double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;

        l = 2;
        if (n > 8) {
            cft1st(a);
            l = 8;
            while ((l << 2) < n) {
                cftmdl(l, a);
                l <<= 2;
            }
        }
        if ((l << 2) == n) {
            for (j = 0; j < l; j += 2) {
                j1 = j + l;
                j2 = j1 + l;
                j3 = j2 + l;
                x0r = a[j] + a[j1];
                x0i = -a[j + 1] - a[j1 + 1];
                x1r = a[j] - a[j1];
                x1i = -a[j + 1] + a[j1 + 1];
                x2r = a[j2] + a[j3];
                x2i = a[j2 + 1] + a[j3 + 1];
                x3r = a[j2] - a[j3];
                x3i = a[j2 + 1] - a[j3 + 1];
                a[j] = x0r + x2r;
                a[j + 1] = x0i - x2i;
                a[j2] = x0r - x2r;
                a[j2 + 1] = x0i + x2i;
                a[j1] = x1r - x3i;
                a[j1 + 1] = x1i - x3r;
                a[j3] = x1r + x3i;
                a[j3 + 1] = x1i + x3r;
            }
        } else {
            for (j = 0; j < l; j += 2) {
                j1 = j + l;
                x0r = a[j] - a[j1];
                x0i = -a[j + 1] + a[j1 + 1];
                a[j] += a[j1];
                a[j + 1] = -a[j + 1] - a[j1 + 1];
                a[j1] = x0r;
                a[j1 + 1] = x0i;
            }
        }
    }

    private void cft1st(double[] a)
    {
        int j, k1, k2;
        double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
        double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;

        x0r = a[0] + a[2];
        x0i = a[1] + a[3];
        x1r = a[0] - a[2];
        x1i = a[1] - a[3];
        x2r = a[4] + a[6];
        x2i = a[5] + a[7];
        x3r = a[4] - a[6];
        x3i = a[5] - a[7];
        a[0] = x0r + x2r;
        a[1] = x0i + x2i;
        a[4] = x0r - x2r;
        a[5] = x0i - x2i;
        a[2] = x1r - x3i;
        a[3] = x1i + x3r;
        a[6] = x1r + x3i;
        a[7] = x1i - x3r;
        wk1r = w[2];
        x0r = a[8] + a[10];
        x0i = a[9] + a[11];
        x1r = a[8] - a[10];
        x1i = a[9] - a[11];
        x2r = a[12] + a[14];
        x2i = a[13] + a[15];
        x3r = a[12] - a[14];
        x3i = a[13] - a[15];
        a[8] = x0r + x2r;
        a[9] = x0i + x2i;
        a[12] = x2i - x0i;
        a[13] = x0r - x2r;
        x0r = x1r - x3i;
        x0i = x1i + x3r;
        a[10] = wk1r * (x0r - x0i);
        a[11] = wk1r * (x0r + x0i);
        x0r = x3i + x1r;
        x0i = x3r - x1i;
        a[14] = wk1r * (x0i - x0r);
        a[15] = wk1r * (x0i + x0r);
        k1 = 0;
        for (j = 16; j < n; j += 16) {
            k1 += 2;
            k2 = 2 * k1;
            wk2r = w[k1];
            wk2i = w[k1 + 1];
            wk1r = w[k2];
            wk1i = w[k2 + 1];
            wk3r = wk1r - 2 * wk2i * wk1i;
            wk3i = 2 * wk2i * wk1r - wk1i;
            x0r = a[j] + a[j + 2];
            x0i = a[j + 1] + a[j + 3];
            x1r = a[j] - a[j + 2];
            x1i = a[j + 1] - a[j + 3];
            x2r = a[j + 4] + a[j + 6];
            x2i = a[j + 5] + a[j + 7];
            x3r = a[j + 4] - a[j + 6];
            x3i = a[j + 5] - a[j + 7];
            a[j] = x0r + x2r;
            a[j + 1] = x0i + x2i;
            x0r -= x2r;
            x0i -= x2i;
            a[j + 4] = wk2r * x0r - wk2i * x0i;
            a[j + 5] = wk2r * x0i + wk2i * x0r;
            x0r = x1r - x3i;
            x0i = x1i + x3r;
            a[j + 2] = wk1r * x0r - wk1i * x0i;
            a[j + 3] = wk1r * x0i + wk1i * x0r;
            x0r = x1r + x3i;
            x0i = x1i - x3r;
            a[j + 6] = wk3r * x0r - wk3i * x0i;
            a[j + 7] = wk3r * x0i + wk3i * x0r;
            wk1r = w[k2 + 2];
            wk1i = w[k2 + 3];
            wk3r = wk1r - 2 * wk2r * wk1i;
            wk3i = 2 * wk2r * wk1r - wk1i;
            x0r = a[j + 8] + a[j + 10];
            x0i = a[j + 9] + a[j + 11];
            x1r = a[j + 8] - a[j + 10];
            x1i = a[j + 9] - a[j + 11];
            x2r = a[j + 12] + a[j + 14];
            x2i = a[j + 13] + a[j + 15];
            x3r = a[j + 12] - a[j + 14];
            x3i = a[j + 13] - a[j + 15];
            a[j + 8] = x0r + x2r;
            a[j + 9] = x0i + x2i;
            x0r -= x2r;
            x0i -= x2i;
            a[j + 12] = -wk2i * x0r - wk2r * x0i;
            a[j + 13] = -wk2i * x0i + wk2r * x0r;
            x0r = x1r - x3i;
            x0i = x1i + x3r;
            a[j + 10] = wk1r * x0r - wk1i * x0i;
            a[j + 11] = wk1r * x0i + wk1i * x0r;
            x0r = x1r + x3i;
            x0i = x1i - x3r;
            a[j + 14] = wk3r * x0r - wk3i * x0i;
            a[j + 15] = wk3r * x0i + wk3i * x0r;
        }
    }

    private void cftmdl(int l, double[] a)
    {
        int j, j1, j2, j3, k, k1, k2, m, m2;
        double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
        double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;

        m = l << 2;
        for (j = 0; j < l; j += 2) {
            j1 = j + l;
            j2 = j1 + l;
            j3 = j2 + l;
            x0r = a[j] + a[j1];
            x0i = a[j + 1] + a[j1 + 1];
            x1r = a[j] - a[j1];
            x1i = a[j + 1] - a[j1 + 1];
            x2r = a[j2] + a[j3];
            x2i = a[j2 + 1] + a[j3 + 1];
            x3r = a[j2] - a[j3];
            x3i = a[j2 + 1] - a[j3 + 1];
            a[j] = x0r + x2r;
            a[j + 1] = x0i + x2i;
            a[j2] = x0r - x2r;
            a[j2 + 1] = x0i - x2i;
            a[j1] = x1r - x3i;
            a[j1 + 1] = x1i + x3r;
            a[j3] = x1r + x3i;
            a[j3 + 1] = x1i - x3r;
        }
        wk1r = w[2];
        for (j = m; j < l + m; j += 2) {
            j1 = j + l;
            j2 = j1 + l;
            j3 = j2 + l;
            x0r = a[j] + a[j1];
            x0i = a[j + 1] + a[j1 + 1];
            x1r = a[j] - a[j1];
            x1i = a[j + 1] - a[j1 + 1];
            x2r = a[j2] + a[j3];
            x2i = a[j2 + 1] + a[j3 + 1];
            x3r = a[j2] - a[j3];
            x3i = a[j2 + 1] - a[j3 + 1];
            a[j] = x0r + x2r;
            a[j + 1] = x0i + x2i;
            a[j2] = x2i - x0i;
            a[j2 + 1] = x0r - x2r;
            x0r = x1r - x3i;
            x0i = x1i + x3r;
            a[j1] = wk1r * (x0r - x0i);
            a[j1 + 1] = wk1r * (x0r + x0i);
            x0r = x3i + x1r;
            x0i = x3r - x1i;
            a[j3] = wk1r * (x0i - x0r);
            a[j3 + 1] = wk1r * (x0i + x0r);
        }
        k1 = 0;
        m2 = 2 * m;
        for (k = m2; k < n; k += m2) {
            k1 += 2;
            k2 = 2 * k1;
            wk2r = w[k1];
            wk2i = w[k1 + 1];
            wk1r = w[k2];
            wk1i = w[k2 + 1];
            wk3r = wk1r - 2 * wk2i * wk1i;
            wk3i = 2 * wk2i * wk1r - wk1i;
            for (j = k; j < l + k; j += 2) {
                j1 = j + l;
                j2 = j1 + l;
                j3 = j2 + l;
                x0r = a[j] + a[j1];
                x0i = a[j + 1] + a[j1 + 1];
                x1r = a[j] - a[j1];
                x1i = a[j + 1] - a[j1 + 1];
                x2r = a[j2] + a[j3];
                x2i = a[j2 + 1] + a[j3 + 1];
                x3r = a[j2] - a[j3];
                x3i = a[j2 + 1] - a[j3 + 1];
                a[j] = x0r + x2r;
                a[j + 1] = x0i + x2i;
                x0r -= x2r;
                x0i -= x2i;
                a[j2] = wk2r * x0r - wk2i * x0i;
                a[j2 + 1] = wk2r * x0i + wk2i * x0r;
                x0r = x1r - x3i;
                x0i = x1i + x3r;
                a[j1] = wk1r * x0r - wk1i * x0i;
                a[j1 + 1] = wk1r * x0i + wk1i * x0r;
                x0r = x1r + x3i;
                x0i = x1i - x3r;
                a[j3] = wk3r * x0r - wk3i * x0i;
                a[j3 + 1] = wk3r * x0i + wk3i * x0r;
            }
            wk1r = w[k2 + 2];
            wk1i = w[k2 + 3];
            wk3r = wk1r - 2 * wk2r * wk1i;
            wk3i = 2 * wk2r * wk1r - wk1i;
            for (j = k + m; j < l + (k + m); j += 2) {
                j1 = j + l;
                j2 = j1 + l;
                j3 = j2 + l;
                x0r = a[j] + a[j1];
                x0i = a[j + 1] + a[j1 + 1];
                x1r = a[j] - a[j1];
                x1i = a[j + 1] - a[j1 + 1];
                x2r = a[j2] + a[j3];
                x2i = a[j2 + 1] + a[j3 + 1];
                x3r = a[j2] - a[j3];
                x3i = a[j2 + 1] - a[j3 + 1];
                a[j] = x0r + x2r;
                a[j + 1] = x0i + x2i;
                x0r -= x2r;
                x0i -= x2i;
                a[j2] = -wk2i * x0r - wk2r * x0i;
                a[j2 + 1] = -wk2i * x0i + wk2r * x0r;
                x0r = x1r - x3i;
                x0i = x1i + x3r;
                a[j1] = wk1r * x0r - wk1i * x0i;
                a[j1 + 1] = wk1r * x0i + wk1i * x0r;
                x0r = x1r + x3i;
                x0i = x1i - x3r;
                a[j3] = wk3r * x0r - wk3i * x0i;
                a[j3 + 1] = wk3r * x0i + wk3i * x0r;
            }
        }
    }

    private void rftfsub(int n, double[] a, int nc, double[] c, int nw)
    {
        int j, k, kk, ks, m;
        double wkr, wki, xr, xi, yr, yi;

        m = n >> 1;
        ks = 2 * nc / m;
        kk = 0;
        for (j = 2; j < m; j += 2) {
            k = n - j;
            kk += ks;
            wkr = 0.5 - c[nw + nc - kk];
            wki = c[nw + kk];
            xr = a[j] - a[k];
            xi = a[j + 1] + a[k + 1];
            yr = wkr * xr - wki * xi;
            yi = wkr * xi + wki * xr;
            a[j] -= yr;
            a[j + 1] -= yi;
            a[k] += yr;
            a[k + 1] -= yi;
        }
    }

    private void rftbsub(int n, double[] a, int nc, double[] c, int nw)
    {
        int j, k, kk, ks, m;
        double wkr, wki, xr, xi, yr, yi;

        a[1] = -a[1];
        m = n >> 1;
        ks = 2 * nc / m;
        kk = 0;
        for (j = 2; j < m; j += 2) {
            k = n - j;
            kk += ks;
            wkr = 0.5 - c[nw + nc - kk];
            wki = c[nw + kk];
            xr = a[j] - a[k];
            xi = a[j + 1] + a[k + 1];
            yr = wkr * xr + wki * xi;
            yi = wkr * xi - wki * xr;
            a[j] -= yr;
            a[j + 1] = yi - a[j + 1];
            a[k] += yr;
            a[k + 1] = yi - a[k + 1];
        }
        a[m + 1] = -a[m + 1];
    }

    private void dctsub(int n, double[] a, int nc, double[] c, int nw)
    {
        int j, k, kk, ks, m;
        double wkr, wki, xr;

        m = n >> 1;
        ks = nc / n;
        kk = 0;
        for (j = 1; j < m; j++) {
            k = n - j;
            kk += ks;
            wkr = c[nw + kk] - c[nw + nc - kk];
            wki = c[nw + kk] + c[nw + nc - kk];
            xr = wki * a[j] - wkr * a[k];
            a[j] = wkr * a[j] + wki * a[k];
            a[k] = xr;
        }
        a[m] *= c[nw + 0];
    }

    private void dstsub(int n, double[] a, int nc, double[] c, int nw)
    {
        int j, k, kk, ks, m;
        double wkr, wki, xr;

        m = n >> 1;
        ks = nc / n;
        kk = 0;
        for (j = 1; j < m; j++) {
            k = n - j;
            kk += ks;
            wkr = c[nw + kk] - c[nw + nc - kk];
            wki = c[nw + kk] + c[nw + nc - kk];
            xr = wki * a[k] - wkr * a[j];
            a[k] = wkr * a[k] + wki * a[j];
            a[j] = xr;
        }
        a[m] *= c[nw + 0];
    }

}


ご自由にお使いください。他人のソースコードを書き換えただけですから。

ではまた。

DJ Snakeの「A Different Way」にハマった

こんにちは。今日は久しぶりに洋楽の話題です。

今日は、DJ SnakeのA Different Wayという曲についてです。

まだPVは公開されていないようですが、非常にいい曲です。

曲の内容は、失恋した女の子に、俺なら幸せにできる!って伝える歌詞のようです。

韻を踏んだリズムのよい歌詞と、その内容にマッチしたメロディーがなんともいえません。

私は、google play musicでこの曲を聞いてからめちゃくちゃハマってしまいました。

レコード会社の回し者みたいになりましたが、みなさんも是非聞いてください!

ではまた。

A Different Way (feat. Lauv)

A Different Way (feat. Lauv)

  • DJスネイク
  • ダンス
  • ¥250

英単語アプリ「Memoria」を公開しました!

f:id:takebo_blog:20170925135928p:plain
こんにちは。今日は私が開発したアプリを紹介させていただきます。

中学生に最適!英単語アプリ「Memoria

今回公開したアプリは、「Memoria」です。

Memoriaは中学生で学習する英単語を収録した英単語アプリです。
英単語は大阪府教育委員会が公表している「大阪版中学校で学ぶ英単語集」を元に選定いたしました。
これは大阪府の公立高校入試にて、出題される英単語を集めたものです。

これを勉強すれば、高校入試に必要な英単語をしっかり暗記することができます。

現代では英語力が必須となってまいりました。
中学校で学ぶ英単語は社会人として覚えていて当然のものばかり!
みなさんも英単語の復習として、ぜひご活用ください。

技術的な話

ということで、宣伝はここまでです。
ここではこのアプリの技術的な話をしたいと思います。

使用したライブラリ

このアプリには、暗記した単語数や学習した時間をグラフで表示する機能があります。
ここでは、「MPAndroidChart」というライブラリを導入しました!
github.com

こちらで使い方が紹介されています。
moneyforward.com

このライブラリは様々なアプリで活用されて、非常に使い勝手のよいライブラリです。
データを設定すれば、アニメーション付きで表示され、とても見た目が美しいグラフが表示されます。
自分で実装するととても大変だと思いますので、非常に便利なライブラリです。

また、ライセンス表示には「AboutLibraries」というライブラリを使用しました。
github.com

こちらで使い方が紹介されています。
cutmail.hatenablog.com

有名なライブラリであれば、ライセンスが自動的に表示されます。
自分で追加することもできます。

日付処理には「ThreeTenABP」を使用しています。
github.com

こちらで使い方が紹介されています。
techblog.timers-inc.com

日付処理は、標準機能では大変扱いにくいものです。
それを簡単にしてくれるのがこのライブラリです。
日付処理はJodaTimeが有名ですが、JodaTimeはヘビーなライブラリという噂をきき、今回はこれを選びました。
これのお陰で1ヶ月前というような処理が簡単に行えるようになりました。
ThreeTenABPはJava8の日付処理APIのバックポートですので、もしAndroidがJava8に対応したとしても、大幅に書き換える必要はありません。

苦労した点

このアプリは私の人生で初めて開発したAndroidアプリです。
知らないことだらけで、すべてに苦戦しました。
単語のリスト表示には大いに悩まされました。

タブとして単語を分けるため、Fragmentを導入したり、リストに画像と文字を並べて表示できるようにしたり。
非常に大変でした。ほんとに苦労しました(笑)
アプリ作りに手慣れた方には非常に簡単なことだと思いますが、私にはチョモランマ級に高い壁でした。
リスト作成時にヒープが足らなくなったり、散々エラーに見舞われました…。

まあ、なにはともあれ完成してよかった!(笑)

ダウンロード

Memoriaはこちらからダウンロード可能です。
残念ながら現在は、Android版のみの公開となっております。
どんな仕上がりになっているか、またバグ探しにご協力ください!
Google Play で手に入れよう