質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.91%

rubyを使った計算方法

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 957

sakuya_izayoi

score 19

ruby を用いた二乗および平方根の計算方法が知りたいです。

rubyで外部ファイル、たとえばtest.txtに
番号 南北方向速度 東西方向速度 鉛直方向速度
1    -1.94E-06    1.33E-06    -2.78E-08
2    -5.00E-06    4.59E-06    -5.14E-08
3    -1.15E-05    1.24E-05    -8.93E-08
4    -3.02E-05    3.64E-05    -1.22E-07
5    -8.43E-05    1.03E-04    -3.38E-07
6    -2.16E-04    2.59E-04    -8.88E-07
7    -1.76E-04    2.09E-04    -1.07E-06
8    -2.49E-04    3.55E-04    -2.31E-07
9    -4.46E-04    6.89E-04    -3.62E-07
10    -8.96E-04    1.36E-03    1.52E-07
11    -1.35E-03    2.00E-03    2.57E-06
以下継続

と記載されているとします。
このファイルを読み込んで
番号    合成速度
1    2.36E-06
2    6.79E-06
3    1.69E-05
4    4.73E-05
5    1.33E-04
6    3.37E-04
7    2.73E-04
8    4.34E-04
9    8.21E-04
10    1.63E-03
11    2.42E-03
以下継続

と計算できる方法はあるのでしょうか?
コマンドライン上に手動で一つずつ値を打ち込む方法は最近分かったのですが、外部ファイルを参照させた場合が分かりません。

行いたい数式としては
{(南北方向速度^2+東西方向速度^2+鉛直方向速度^2)}^(1/2)
であります。(一般的な3次元合成ベクトル求める計算式です。)
test.txtはスペース区切りの場合とカンマ区切りの場合があります。(カンマ区切りの場合はスペース区切りに一括置換は可能でした。)

エクセルでやればよいと思ったのですが、行数がやたらと多く、エクセルがハングアップしてしまい困ってしまいました。
質問するだけになり、申し訳ありませんがお答えいただけたら幸いです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+3

calc.rb

FILE_NAME = 'data.txt'
OUT_COL_NAMES = '番号 合成速度'

def calc(line)
  _, x, y, z = line.gsub(',', ' ').split.map { |s| s.to_f }
  result = Math.sqrt(x ** 2 + y ** 2 + z ** 2)
end

File.open(FILE_NAME, 'r') do |f|
  f.each_line.with_index { |line, idx|
    out_line = idx.zero? ? OUT_COL_NAMES : "#{idx}#{sprintf('%10.2E', calc(line))}"
    puts out_line
  }
end

data.txt

番号 南北方向速度 東西方向速度 鉛直方向速度
1    -1.94E-06    1.33E-06    -2.78E-08
2    -5.00E-06    4.59E-06    -5.14E-08
3    -1.15E-05    1.24E-05    -8.93E-08
4    -3.02E-05    3.64E-05    -1.22E-07
5    -8.43E-05    1.03E-04    -3.38E-07
6    -2.16E-04    2.59E-04    -8.88E-07
7    -1.76E-04    2.09E-04    -1.07E-06
8    -2.49E-04    3.55E-04    -2.31E-07
9    -4.46E-04    6.89E-04    -3.62E-07
10    -8.96E-04    1.36E-03    1.52E-07
11    -1.35E-03    2.00E-03    2.57E-06
12, -1.35E-03, 2.00E-03, 2.57E-06

実行例

$ ruby calc.rb
番号 合成速度
1  2.35E-06
2  6.79E-06
3  1.69E-05
4  4.73E-05
5  1.33E-04
6  3.37E-04
7  2.73E-04
8  4.34E-04
9  8.21E-04
10  1.63E-03
11  2.41E-03
12  2.41E-03

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/04 00:47

    katoy様。ありがとうございます。
    _, x, y, z = line.gsub(',', ' ').split
    のところで、列に名前を付けるのですか。それで、どの列を計算しなさいという指示を出す、という塩梅でしょうか?
    (',', ' ').split
    というのはカンマ区切りスペース区切りどちらでも区切ってくれる構文なのですね。初めて知りました。

    上記を参考にというよりは、上記をほとんど使わさせていただき、計算結果ファイルが欲しかったため、追記させていただきました。そして私の環境では文字コードのエラーが出てしまったため、頭にも魔法の言葉?を付けさせてもらいました。
    "Ruby"
    # encoding: shift_JIS

    FILE_NAME = 'data.txt'

    OUT_COL_NAMES = '番号 合成速度'
    def calc(line)
    _, x, y, z = line.gsub(',', ' ').split.map { |s| s.to_f }
    result = Math.sqrt(x ** 2 + y ** 2 + z ** 2)
    end

    File.open(FILE_NAME, 'r') do |f|
    result = File.open('result.out', "w")

    f.each_line.with_index { |line, idx|
    out_line = idx.zero? ? OUT_COL_NAMES : "#{idx}#{sprintf('%10.2E', calc(line))}"
    puts out_line

    result.puts out_line
    }
    end
    "Ruby"

    一応、結果が書き出せたのですが、あぶなそうであれば教えていただけると幸いです。

    キャンセル

  • 2017/04/04 06:44

    > line.gsub(',', ' ').split
    これは、 line 中の すべての "," を " " に置き換えてから " " で区切るということをしています。

    キャンセル

  • 2017/04/04 07:55

    ああ、そういう事なんですね。だからどちらでも大丈夫であるという事ですね。
    ありがとうございました。ベストアンサーにさせていただきます。

    キャンセル

+2

必要になりそうな処理だけ個別に記載します。

二乗

2 ** 2 # => 4

平方根

Math.sqrt(2) # => 1.414213562373095

ファイルの読み取り

File.open("test.txt", "r") do |f|
  puts f.read
end

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る