C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: ジェネリックな行列クラスの算術演算


(過去ログ 17 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■6623 / inTopicNo.1)  ジェネリックな行列クラスの算術演算
  
□投稿者/ yagiey (18回)-(2007/08/21(Tue) 00:06:53)

分類:[.NET 全般] 

ジェネリックな行列クラスMatrix<T>を実装しようとしてます。
型引数(って言うのかな...。Tのことです)は行列の要素の型です。
つまり、Matrix<double>とやると要素がdoubleの行列ができます。

さて、この行列クラスに和や積などの演算を定義しようとして悩んでます。
Tそのままだと、Tに和や積が定義されていないのでコンパイラにこっぴどく叱られます。
んで、C#では型引数に制約がかけられるらしく、喜び勇んで使ってみました。
class Matrix<T> where T : IComparable<T>, IAddable<T>, IMultiplyable<T>, Iほげ, Iはげ { ... }
てな感じです。いくつかのインターフェースは自前のものです。
しかし、Tがdoubleやintのとき、doubleやintは上記の「俺様インターフェース」を実装しないので使えんのです。

IAddable<T>やIMultiplyable<T>に相当する、intやdoubleも実装している.net framework標準のインターフェースなんてものはありませんか?
IComparable<T>はあるのになぁ...。
そうでなくとも、何とかならんでしょうか?

# ってか、行列の要素にintやdouble以外はあんまし考えられんのかも知れませんが...
引用返信 編集キー/
■6627 / inTopicNo.2)  Re[1]: ジェネリックな行列クラスの算術演算
□投稿者/ Hongliang (168回)-(2007/08/21(Tue) 06:28:31)
Hongliang さんの Web サイト
> IAddable<T>やIMultiplyable<T>に相当する、intやdoubleも実装している.net framework標準のインターフェースなんてものはありませんか?
ないです。

> そうでなくとも、何とかならんでしょうか?
型をラップする構造体を作る(Nullable ジェネリック構造体と同じ発想)。
とか、
演算をデリゲートで渡してもらう。
とか。
引用返信 編集キー/
■6629 / inTopicNo.3)  Re[2]: ジェネリックな行列クラスの算術演算
□投稿者/ 囚人 (134回)-(2007/08/21(Tue) 08:59:10)
要素を double にしておくのが一番楽そうですね。
Matrix<int> の型があっても、常に Matrix<double> 使いそう(Matrix<int> を使う機会がない)。
引用返信 編集キー/
■6635 / inTopicNo.4)  Re[3]: ジェネリックな行列クラスの算術演算
□投稿者/ も (1回)-(2007/08/21(Tue) 12:33:17)
# Haskellの型クラスのようなものって用意されてないのかな?

擬似コードで。

interface Num<T>{
  //実際はインタフェイスで、ここではNum<T>は実装されていない。
  //要は Num<T> 型は基本的な演算が行えるという型のクラス
  
  T negate(T) // Num<Int>なら実装は negate(Int x)=-x 見たいな感じ
  T add(T, T)
  T sub(T, T)
  T mul(T, T)
}

interface Linear<T>{
  T Scaled(double, T) // Scaled(double x, T a)=x*a
}

class Matrix<Num<T>> extends Num{
  //Matrixは基本的な演算が行えるので、Numを継承している
  //Matrixは唯の<T>ではなく、基本的な演算を受け付ける<T>
  Matrix<Num<T>> negate(Matrix<Num<T>>)
  add...
  mul..
}

// 内部が行列の行列とか。
Matrix<Matrix<Int>> Matroska_Matrix

※あっ・・・: http://blogs.wankuma.com/trapemiya/archive/2006/07/06/31783.aspx

引用返信 編集キー/
■6640 / inTopicNo.5)  Re[4]: ジェネリックな行列クラスの算術演算
□投稿者/ yagiey (19回)-(2007/08/21(Tue) 14:07:03)
> 型をラップする構造体を作る(Nullable ジェネリック構造体と同じ発想)。
Nullable<T>は使ったことなかったんで調べてみました。
値型Tがnull値を持てるようにしたものですよね。
Nullable<T>とTは相互に暗黙の型変換があり、相違点といえばnull代入の可否だけですね。
うーん、スムーズに動きますねー。
こーいうのを「型をラップした構造体」っていうんですか。
しかしながら、この発想が、私が悩んでいる問題にどう応用できるかが理解できません。
理解力が乏しいもんで...。すんません。

> 演算をデリゲートで渡してもらう。
これは僕にもわかりますよー(笑)。検討してみます。


> 要素を double にしておくのが一番楽そうですね。
> Matrix<int> の型があっても、常に Matrix<double> 使いそう(Matrix<int> を使う機会がない)。
例えばMatrix<int>を使ってても、もし逆行列の計算なんかやっちゃうとintじゃマズいですね。
うん、コレが一番簡単ですね。


> ※あっ・・・: http://blogs.wankuma.com/trapemiya/archive/2006/07/06/31783.aspx
なるほどー、計算機をメンバに持っといて、計算はそいつに委譲するんですね。
まだメリット・デメリットに関して考察していないので、考えてみます。



過去ログに
http://bbs.wankuma.com/index.cgi?mode=al2&namber=7477&KLOG=7
をハケーン!
templateとgenericsは違うんだなー、って実感...。

解決済み
引用返信 編集キー/
■6657 / inTopicNo.6)  Re[1]: ジェネリックな行列クラスの算術演算
□投稿者/ れい (46回)-(2007/08/21(Tue) 15:50:02)
No6623 (yagiey さん) に返信
> ジェネリックな行列クラスMatrix<T>を実装しようとしてます。
> # ってか、行列の要素にintやdouble以外はあんまし考えられんのかも知れませんが...

No6629 (囚人 さん) に返信
> 要素を double にしておくのが一番楽そうですね。
> Matrix<int> の型があっても、常に Matrix<double> 使いそう(Matrix<int> を使う機会がない)。

行列の中にControlとかは無いですが、
行列の中に行列とか、
行列の中に数式とか、
行列の中に無限精度整数とか、
そーゆーのはかなり使います。使えます。

行列演算の高速な実装は非常にめんどくさいので、
Doubleでしか使えないなんて、もったいないです。

実際、私はよく使います。
振動解析とか超関数の解析するときとか。

私は基本型を構造体でラップして使ってます。
デリゲートで渡すのは遅かったのと、わかりづらかったので。
(intに割り算が定義されてるのも気に食わなかったとか言う理由もあります)

きちんと作っておくと、見た目きれいで
わかりやすいものができます。

まぁ本気でやるときはスパコンで専用ライブラリでないと速度がきついんで、
.Netの実装はお勉強程度になってしまいますが。

> class Matrix<T> where T : IComparable<T>, IAddable<T>, IMultiplyable<T>, Iほげ, Iはげ { ... }

それを言うならIほがぶる,Iはがぶるかと。

引用返信 編集キー/
■6659 / inTopicNo.7)  Re[2]: ジェネリックな行列クラスの算術演算
□投稿者/ 囚人 (139回)-(2007/08/21(Tue) 16:10:12)
速度とかどうとか言い出すなら C++ template かな。

> 私は基本型を構造体でラップして使ってます。
> デリゲートで渡すのは遅かったのと、わかりづらかったので。
> (intに割り算が定義されてるのも気に食わなかったとか言う理由もあります)

つか、基本型を使いたいだけなのにラップしないといけないのがメンドイですね。
でも、確かに行列とか数式は使いたいですね。

今思いついたんですけど、こんなの用意したらいけるんじゃない? って気がしてきた。
#環境なくて試せず。

class MatrixElement : IComparable, IAddable, IMultiplyable, Iほげ, Iはげ 
{
	public static implicit operator MatrixElement(double d)
	{
		//..
	}
}

で、
Matrix<MatrixElement> m = new Matrix<MatrixElement>();
m[0, 0] = 1.0; // これいけるかな?

引用返信 編集キー/
■6669 / inTopicNo.8)  Re[3]: ジェネリックな行列クラスの算術演算
□投稿者/ れい (47回)-(2007/08/21(Tue) 19:49:17)
No6659 (囚人 さん) に返信
>速度とかどうとか言い出すなら C++ template かな。

.NetのGenericを使って数値計算や数式計算させるといいのは、
すごく綺麗に書けることなんですよね。それ以外に利点は何もないかも。
ちょっと思いついたときにすぐ実行してみるのにすごくいい。

>つか、基本型を使いたいだけなのにラップしないといけないのがメンドイですね。
>今思いついたんですけど、こんなの用意したらいけるんじゃない? って気がしてきた。

おぉ。
一々ラップしなくてもいけそうですね。すばらしい。

今見たら、私のライブラリも、浮動小数点型を定義してdoubleとfloatからimplicitに変換してた。
無限精度整数型も作って、これは各種整数型から変換してました。

たしか、基本型は数値計算するのにいろいろ問題あったので、
結局doubleをラップした浮動小数点型と
無限精度整数型を作ったような気がします。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -