yamicha.com's Blog - Presented by yamicha.com
Blog yamicha.com's Blog - 2018/12 の記事
[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31]

yamicha.com's Blog
 諸事情により、現在更新休止中。ご了承ください。もし今後ブログを再開することがあるとすれば、その際にはこのブログスクリプトではなく、新しく開発したものによるかもしれません。
 当ブログ管理者についてはこちらをご参照。
開発魔法(737)
社会問題(733)
お知らせ(11)
質問・バトン回答(15)
ゲスト出演(8)
経済・知的財産(150)
ゲーム開発(182)
[Ada] 勝手に補足
- Note
- 金配りの次の一手


- Endless Ultimate Diary
- 銃世界

漢字バトン
- うるる雑記帳
- 漢字接力棒

ツキアイゲノムバトン
- ブログ@うにうに画像倉庫
- あぶ内閣

縺イ縺セ縺、縺カ縺励ヰ繝医Φ
- 月夜のボヤキ
- 騎士サーラバトン
パスワードを使う
名無し (2012/02/27)


開発者解放裁判
yamicha.com (2010/03/14)
Winnyに関しては、私も「純白」とまでは考えておりませんし、使用し..

開発者解放裁判
通りすがり (2010/03/08)
winnyに関しては「ダウンロードソフト板」なんてところを拠点に開発..

新型インフルエンザの恐怖
いげ太 (2009/11/03)
> C#などの「int Some(int , int)」は、F#では「(int * int) ->..

時効に関する思考
yamicha.com (2009/08/31)
>いげ太さんコメントありがとうございます。手元にドキュメントが少..
Homepage
Blog Top
Normal View
List View
Search
Calendar
Comment List
Trackback List
Blog RSS
Send Trackback
Phone Mode
Administrator
yamicha.com
Blog
るううるる。
Source
法令データ提供システム
FindLaw
Development
Java2 Platform SE 6
Java EE 6 API
MySQL Developer Zone
PHP Reference
MSDN Library
Ada Reference Manual
Objective Caml
Python Documentation
Erlang
Prolog Documents
私的利権権益補償金
2008/05/10(Sat)00:13:38
 著作権利権団体の主張をほぼ丸のみして作られた「テレビ番組のダビング10(コピー9回制限)を導入したければ、iPodなどへの私的録画録音補償金を認めよ」という脅迫案が、メーカーの反対によって見送りとなりました。この案ではiPodなど携帯音楽プレイヤーには課金するものの、PC用HDDなどの汎用性が高い機器には課金しないものとされていますが、メーカー側は「対象が際限なく拡大する恐れがある」として反対しています。
 現状では、デジタル放送には「コピーワンス」と呼ばれる制限がかかっており、DVDなどのメディアには1回しかコピーすることができません。また、DVDにコピーすると元のデータは削除されるため、もしDVDへのコピーが失敗してしまえば、コピーしようとした映像は永久に失われます。本来ならコピー制限を解除して対応すべきところなのですが、ここで出された奇策が「ダビング10」でした。これは9回までコピーが可能で、10回目はコピー後に元のデータが削除されます。
 一方、携帯音楽プレイヤーへの課金はかねてから著作権利権団体が強く主張していたもので、現状ではCDやDVDレコーダー、CD及びDVDのメディア自体の他、携帯音楽プレイヤーに似たものとしては携帯MDレコーダーなどに課金されています。これらの機器やメディアの購入代金には補償金が含まれており、著作権利権団体に渡るようになっています。当然のことながら、CDやDVDをデータ保持や自分の創作物のために利用しても課金されます。
 最近のなりふり構わない著作権利権団体の横暴には驚かされますが、コピー制限を課すこと自体は現状と何ら変わらない、「ダビング10」などという卑劣なおためごかしによって、音楽プレイヤー課金への譲歩を引き出そうとは、卑怯としか言いようがありません。このようなやり口は、製品の質によって売り上げが落ちたのを違法コピーのせいにして、CDにコピーガードをかけて販売した音楽メーカーのそれと全く同じです。
 メーカーが携帯音楽プレイヤー課金に反対したのは、とりあえず妥当な措置といえるでしょう。そもそも私的録画録音補償金自体が不透明かつ不当なものですし、これを音楽プレイヤーに課金されるいわれはありません。さらに、今回の脅迫的な交換条件に用いられているデジタル放送コピー制限の緩和は、本来音楽プレイヤーとは何の関係もありません。また、著作権利権団体のなりふり構わぬ行動からして、これを認めれば今後PC用HDDなどあらゆる装置に対して課金を要求してくる可能性が極めて高く、ここで断固として拒絶する必要があります。
 そもそもメーカーはダビング10自体を受け入れるべきではありません。コンテンツにコピー制限を課すこと自体が問題であり、コピー回数が10回でも256回でも制限されている限りは意味がありません。また、デジタル放送を放送局らによる独占利権企業B-CASが牛耳っていることが問題の根底にあり、これらを打破しない限り利用者不在の状況は続きます。
 著作権利権団体側は「製作者の権利を守るために必要」などと聞こえの良いことばかり主張していますが、百歩譲って現行の補償金制度が妥協点としてやむを得ないものであるとしても、コピーワンスやダビング10では私的録画が大幅に制限されるのですから、少なくともこれらを行うレコーダーについては補償金を課すことはできないか、または著しく減額しなければならないはずです。その上、基本的に音楽や映像を保存することしかできないVHSやDVD、MDレコーダーと、HDDにデータを保存することができる携帯音楽プレイヤーでは、質的に大きな違いがあることは否めませんので、仮に現状を肯定したとしても課金を容認する理由にはなりません。ましてや、PCのHDDにまで課金するなど論外です。
 文化庁も文化庁で、著作権利権団体の代弁者となるのではなく、多少はコンテンツ利用者の方を向くべきでしょう。おそらく裏で金銭授受なり天下りなりが行われていることが想像できますが、それにしても昨今の利権団体の横暴にはすさまじいものがあります。今回の例を見るまでもなく、文化庁は私的録画録音補償金の導入や拡大を推進している他、著作権の期限が切れる映画について屁理屈同然の主張を行い、より著作権期限を長くみなすようなこじつけを行っていました。無論、このような文化庁の主張が認められるわけもなく、裁判にて期限切れが認定されました。
 著作権利権団体にしても、横暴な論理でくだらない主張を繰り返すより、まずは作品の質を考えるべきでしょう。無限回のコピーやインターネットへのアップロードが可能であるとしても、良い製品であれば何の問題もなく売れますし、いくらコピーガードなどの利用者締め付けを強めたところで、悪いものは売れません。これはCCCD騒動を見ての通りです。作品の質を棚上げし、利用者を締め付けた上に補償金を少しでも多くふんだくろうなどとは、コンテンツ作成者の風上にも置けません
 音楽プレイヤーばかりかPCのHDDなどにも課金することになって人々の怒りを買い、デジタル放送のコピー制限は存続して利用者に不便を強い、それでいて一部の技術者によって放送の暗号化が破られ、一般利用者が制限に苦しむ中で裏の利用者のみがコピーを解除してインターネット配信なり非合法DVDなりを作る、という結末が見えるようです。

 京都・舞鶴の事件で、遺族がマスコミに手記を発表しました。毎度のことながら報道自粛を申し入れる文言が盛り込まれており、またしても報道被害が発生していることが分かります。さらに、これも毎度のことではありますが、マスコミによってはこの手記の全文を引用することはなく、事件について語った部分のみを引用した上で、報道被害については「自粛を申し入れた」とだけ書いて済ませています。
 特にひどいのが読売新聞のWebサイトでの引用で、犯人について「絶対に許すことはできません」とした部分まで手記を引用していながら、その後に続く「マスコミの皆様〜」の部分を全部切り落として隠蔽しています。報道の権力を盾にした言論封殺行為も同然です。
 いつも不思議で仕方がありませんが、報道協定を結ぶなり節度ある取材を申し合わせるなりしてもこのような取材を行う有様なのでしょうか。それとも、遺族に言われなければ節度ある取材をしないのでしょうか。どちらにしてもあきれ果てる所業というしかなく、「被害者は2度死ぬ」ことをまざまざと示しています。
 これまでにも再三取り上げているように、このような悪質な取材は今に始まったことではなく、以前に女児殺害が連続して発生した際にもほぼ例外なく遺族がマスコミの横暴を訴え、遺族の自宅に無断で不法侵入したり、家の前に空き缶やタバコの吸殻を投げ捨てていることが明らかになりました。また、被害者の関係者宅に押しかけて写真を譲り受けたり購入したりすることも常態化しているようです。以前に精神科医の調書漏えいや報道のねつ造などが発覚した際、マスコミは報道の自殺などとして大げさに騒ぎ立てましたが、このような野蛮な取材行為を行うことこそ報道の自殺です。
 こうした残虐極まりない取材に対し、見るに見かねて誰か(主に政治家など有力者)が苦言を呈しでもしようものなら、必ず「報道の自由の侵害だ」「国民の知る権利だ」などという意味不明な主張によってマスコミの大反発を浴びることになりますが、報道の責任を守らぬ以上は報道の自由はありませんし、被害者の家にタバコや空き缶を撒き散らした上での取材結果や葬式に押しかけた挙句の取材結果を見たいと望む国民はそうそういないでしょう。
 報道被害を防止する組織としてBROなどがありますが、所詮はアリバイ工作の延長線上の組織に過ぎず、十分な効果が期待できないのが現状です。被害者に対する報道被害は一向になくなりませんし、被疑者は相変わらず犯人扱いされるばかりか、科学的根拠のない血液型占いの1つたりともやめさせることができません。
 現代社会では誰でも事件の被害者になる可能性がありますし、冤罪で犯人にされてしまう可能性もあります。どちらにしてもマスコミにとことんなまでにプライバシーを暴かれ、名誉をズタズタに毀損される結末となります。いつ自分がその立場に立たされるか分からない以上、他人事では済まされません。
 報道被害が発生するたび、マスコミは自主規制の効果と権力介入の不当性を唱えてきましたが、自主規制は一向に進展を見せません。時間は十分すぎるほどありましたが、どうやらマスコミに改善する意思はないようです。自主規制によって報道被害を抑制することが絶対に不可能であると分かった以上、場合によっては免許剥奪もある非常に厳しい罰則を設け、報道被害による2度目の殺人やセカンドレイプから被害者を守るしかありません。法による介入を控えて自主規制に任せている限り、報道被害が改善することは未来永劫、120%起こりません。
 法によって報道被害から被害者を守るとなれば、権力による恣意的な運用ができないようにする必要はありますが、報道の責任を果たさぬ報道の自由があり得ない以上、「報道の自由の侵害」の声を恐れてはいけません。今のところこのような法案が出される予定は見られませんが、可能な限り早い段階での制定を希望します。

 続・Haskell。今回はHaskellでマトリックスです。とはいえ、これはやや以前に組んだものであり、Sequenceの使い方があまり分からない状態で作っているため、少々無駄が多いのではありますが。
 まずはHaskellのクラスモデルのおさらいから。Haskellにはclassとdataがあり、classは主にプロトタイプ宣言を記述するもので、dataは構造体に類似しています。Javaに例えるとclassはインタフェースに似ていますが、Haskellのクラス内では関数の宣言を行うことができます。ただし、クラス自体は抽象的なものであって実体となるデータを持たないため、クラス内で定義されたオペレーションを組み合わせて実現できる処理のみを実装することしかできません。
class PlusClass a where
	zero :: a
	plus :: a -> a -> a
	multi :: a -> Integer -> a
	-- multi の処理が「zero に対して指定された回数だけ値を足し合わせる」
	-- ものであれば、クラス内の関数宣言のみを使って構築可能であるため
	-- クラス内で実装を定義できる
	-- この実装が不適切なら instance でオーバーライドできる
	multi a m = recmulti a m zero where
		recmulti a m result
			| m > 0 = recmulti a (m - 1) (result `plus` a)
			| otherwise = result

data IntegerData = IntegerData{
	var :: Integer
}

instance PlusClass IntegerData where
	zero = IntegerData 0
	plus a b = IntegerData $ (var a) + (var b)

main = var $ (IntegerData 16) `multi` 16
-- class 内での実装のおかげで、結果は 256
 性質こそインタフェースに似ていますが、HaskellのクラスはHaskellのクラス以外の何者でもありません。
 次にdata、これはほとんど構造体です。構造体と違うのは、instance宣言によって特定のクラスと結びつけ、実装を提供できる点です。これは「Haskellのクラスたるインタフェースをインプリメントしたクラス」と似ていますが、やはりHaskellのインスタンスであるとしか言いようがないものです。つまり、Haskellはdataごとに固有の実装を持ちます。無理にOOPに例えるより、発想を転換して考えた方が理解は容易です。
 ちなみに、クラスには複数の型を取るものがありますが、これはStateなどで平気で使われているにもかかわらず、Haskell 98標準には含まれていない上、仕様としても要検討とされているものです。
 クラスには、型を用いるものと「型のタグ付け」を行うものの2種類があります。通常のクラスは大抵が前者で、後者はモナドが有名です。「タグ付け」を行うと、タグにされた型が独自にデータを持つことができます。以下にごく単純な例を示します。
-- このクラスは通常のデータ型と違い、「タグ」に用いる
class CountTag m where
	inc :: m a -> m a
	dec :: m a -> m a
	getcount :: m a -> Integer
	make :: a -> m a

-- そのインスタンスは対象のデータを保持するようにする
data CountData a = CountData{
	count :: Integer ,
	member :: a
}

-- インスタンスを生成
instance CountTag CountData where
	inc a = a{count = (count a) + 1}
	dec a = a{count = (count a) - 1}
	getcount a = count a
	make a = CountData 0 a

-- CountData が String とは別にデータを持っている点に注目
-- 当然のことながら、String のデータも問題なく保持されている
some :: CountData String
some = inc $ make "SomeData"
main = getcount some
 おさらいはここまでにして、マトリックスの実装です。
import Data.List
import Data.Foldable
import Maybe
import Data.Sequence

-- Matrix
data Matrix = Matrix{
 matrixData :: [[Double]]
}

class (Show a) => MatrixOperation a where
 cols :: a -> Int
 rows :: a -> Int
 get :: a -> Int -> Int -> Double
 set :: a -> Int -> Int -> Double -> a
 multiply :: a -> a -> a
 getList :: a -> [[Double]]
 getListT :: a -> [[Double]]
 inverse :: a -> Maybe a

instance MatrixOperation Matrix where
 cols m = Prelude.length $ (matrixData m) !! 0
 rows m = Prelude.length $ matrixData m
 get m r c = ((matrixData m) !! r) !! c
 set m r c s = m{matrixData = newRows} where
  getCols = (matrixData m) !! r
  newRows = toList $ update r newCols (fromList (matrixData m))
  newCols = toList $ update c s (fromList getCols)
 multiply m n = Matrix (multirc (getList m) (getListT n) []) where
  multirc (mr:mrs) nrs result = multirc mrs nrs 
   (result ++ [multic mr nrs []])
  multirc [] nrs result = result
  multic mr (nr:nrs) result = multic mr nrs (result ++ [prod mr nr 0])
  multic mr [] result = result
  prod (m:mr) (n:nr) result = prod mr nr (result + m * n)
  prod [] [] result = result
 getList m = matrixData m
 getListT m = transpose (matrixData m)
 inverse m = (swappingList (initialList 
  (matrixData m) (rows m)) (rows m)) >>= 
  (inverseList (rows m)) >>= 
  (return . Matrix . (map (Prelude.drop (rows m))) . toList) where
  initialList l size = initialrc l 0 [] size
  initialrc (mr:mrs) i result size = initialrc mrs (i + 1) 
   (result ++ [mr ++ (naturalRow i size)]) size
  initialrc [] i result size = result
  naturalRow i size = (replicate i 0) ++ [1] ++ 
   (replicate (size - i - 1) 0)
  swappingList list size = swapping (return (fromList list)) size
  swapping seq size = seq >>= (checkSwap 0 size)
  checkSwap i size seq
   | i >= size = return seq
   | (seq `index` i) !! i == 0 = (return seq) >>= 
    (searchSwap i size) >>= (checkSwap (i + 1) size)
   | otherwise = (return seq) >>= (checkSwap (i + 1) size)
  searchSwap i size seq = search i 0 size seq
  search :: Int -> Int -> Int -> 
   Seq [Double] -> Maybe (Seq [Double])
  search rowi i size seq
   | i >= size = Nothing
   | (((seq `index` rowi) !! i) /= 0) && 
    (rowi < i || (((seq `index` i) !! rowi) /= 0)) = 
    return $ flip rowi i seq
   | otherwise = search rowi (i + 1) size seq where
    flip i1 i2 seq = update i2 (seq `index` i1) 
     (update i1 (seq `index` i2) seq)
  inverseList :: Int -> Seq [Double] -> Maybe (Seq [Double])
  inverseList size seq = inversing 0 size seq
  inversing i size seq
   | i >= size = return seq
   | otherwise = (return seq) >>= (setDivLine i) >>= 
    (iterMinusLine i 0 size) >>= (inversing (i + 1) size)
  setDivLine :: Int -> Seq [Double] -> Maybe (Seq [Double])
  setDivLine i seq = setDivLineExec i seq ((seq `index` i) !! i) where
   setDivLineExec i seq d
    | d == 0 = Nothing
    | otherwise = return $ adjust (\list -> (Prelude.take i list) ++ 
     (map (\x -> x / d) (Prelude.drop i list))) i seq
  iterMinusLine :: Int -> Int -> Int -> Seq [Double] -> 
   Maybe (Seq [Double])
  iterMinusLine row i size seq
   | i >= size = return seq
   | i == row = iterMinusLine row (i + 1) size seq
   | otherwise = iterMinusLine row (i + 1) size (setMinusLine row i seq)
  setMinusLine row i seq = update i (minusLine row i seq) seq
  minusLine row i seq = (Prelude.take row (seq `index` i)) ++ 
   (minusExec (Prelude.drop row (seq `index` row)) 
   (Prelude.drop row (seq `index` i)) ((seq `index` i) !! row) [])
  minusExec (r:rs) (x:xs) prod result = minusExec rs xs prod 
   (result ++ [x - (r * prod)])
  minusExec [] [] prod result = result

instance Show Matrix where
 show m = show $ matrixData m
 これで完成です。関数名はほとんど見ての通りで、getListTはtransposeしたリストを返すものです。transposeはリストのX,Yを入れ替えるもので、Haskellリファレンスでは次のように説明されています。これはmultiply演算に便利です。
transpose [[1,2,3],[4,5,6]] == [[1,4],[2,5],[3,6]]
 後はMatrixコンストラクタにDoubleの2次元配列を渡せば、乗算でも何でも好きな動作を行うことができます。inverse関数で逆行列を求めることもできますが、逆行列は失敗する場合があるため、Maybeモナドを使用しています。乗算してその逆行列を求め、それをさらに乗算するような場合、Maybeを次々と組み合わせることで、成功すれば演算の結果を得られ、失敗ならNothingを返すことができます。
 しかし、手作業でマトリックスを構築するのはかなり骨ですので、ヘルパークラスを用意してみました。
class (MatrixOperation a) => MatrixCreator a where
 -- 指定したサイズのマトリックスを生成
 createMatrix :: Int -> Int -> a

 -- 乗算しても何もしないマトリックスを生成
 -- createNatural は X,Y,Z、createNaturalH は X,Y,Z,H
 -- (以下に記述した instance 宣言の実装の場合。以下同様)
 -- createNaturalCustom は指定した次元のそれを生成する
 createNatural :: a
 createNaturalH :: a
 createNaturalCustom :: Int -> a

 -- 「位置」を表すマトリックスを生成する
 -- これに対して回転やスケーリングを次々と乗算していくことで
 -- 操作実行後の位置を求められる
 createPosition :: Double -> Double -> Double -> a
 createPositionH :: Double -> Double -> Double -> a

 -- 回転を行うマトリックスを生成する
 -- 1つ目の引数が回転軸、2つ目が度数(rad)
 createRotate :: Int -> Double -> a
 createRotateH :: Int -> Double -> a

 -- 移動を行うマトリックスを生成する
 -- 移動軸である H が必須である
 createMoveH :: Double -> Double -> Double -> a

 -- スケーリングを行うマトリックスを生成する
 createScale :: Double -> Double -> Double -> a
 createScaleH :: Double -> Double -> Double -> a

instance MatrixCreator Matrix where
 createMatrix x y = Matrix $ replicate y (replicate x 0)
 createNatural = createNaturalCustom 3
 createNaturalH = createNaturalCustom 4
 createNaturalCustom a = natural (createMatrix a a) 0 a where
  natural result i m
   | i < m = natural (set result i i 1) (i + 1) m
   | otherwise = result
 createPosition x y z = Matrix [[x , y , z]]
 createPositionH x y z = Matrix [[x , y , z , 1]]
 createRotate a t = setRotate petern createNatural a t where
  setRotate ((a1 , a2 , oper):xs) m a t = setRotate xs 
   (set m (axis (a1 + a)) (axis (a2 + a)) (oper t)) a t
  setRotate [] m a t = m
  petern = [(1 , 1 , cos) , (1 , 2 , sin) , 
   (2 , 1 , (sin . (*)(-1))) , (2 , 2 , cos)]
  axis x = x `mod` 3
 createRotateH a t = setRotate petern createNaturalH a t where
  setRotate ((a1 , a2 , oper):xs) m a t = setRotate xs 
   (set m (axis (a1 + a)) (axis (a2 + a)) (oper t)) a t
  setRotate [] m a t = m
  petern = [(1 , 1 , cos) , (1 , 2 , sin) , 
   (2 , 1 , (sin . (*)(-1))) , (2 , 2 , cos)]
  axis x = x `mod` 3
 createMoveH x y z = setMove createNaturalH [x , y , z] 0 where
  setMove m (x:xs) i = setMove (set m 3 i x) xs (i + 1)
  setMove m [] i = m
 createScale x y z = setScale (createMatrix 3 3) [x , y , z] 0 where
  setScale m (x:xs) i = setScale (set m i i x) xs (i + 1)
  setScale m [] i = m
 createScaleH x y z = setScale (createMatrix 4 4) [x , y , z] 0 where
  setScale m (x:xs) i = setScale (set m i i x) xs (i + 1)
  setScale m [] i = m
 それでは実際に使ってみましょう。まずは単純に、1,0,0をZ軸で45度回転させ、それからX2,Y2,Z5だけ移動させてみます。
main = show $ (createPositionH 1 0 0::Matrix) `multiply` 
	(createRotateH 2 (pi / 4)) `multiply` (createMoveH 2 2 5)
-- "[[2.70710678118655,2.70710678118655,5.0,1.0]]"
 最後の1.0はH軸ですから関係ないとして、1,0,0をZ軸45度回転で0.7071...,0.7071...,0、それを2,2,5動かせば上記の通りの結果となります。
 逆行列も試してみましょう。以下の式では「Z軸45度」を「Z軸45度の逆行列」で打ち消しているため、マトリックス乗算の単位元が返されることになります。
main = (createRotateH 2 (pi / 4)::Matrix) `multiply` 
	(fromJust (inverse (createRotateH 2 (pi / 4)::Matrix)))
-- [[1.0,0.0,0.0,0.0],[0.0,1.0,0.0,0.0],[0.0,0.0,1.0,0.0],[0.0,0.0,0.0,1.0]]
 無論、いつでもどこでもinverseが成功するとは限りません。例えば下記の例の場合、dには次の値が格納されます。
1	0	0	0
0	0	0	0
0	0	1	0
0	0	0	1
 これはinverseできませんので、Nothingとなります。Maybeを使用しているのはそのためで、この場合の結果はNothingとなります。
main = do
	let a = createPositionH 1.0 0 0::Matrix
	let b = createRotateH 2 (pi / 8)::Matrix
	let c = a `multiply` b
	d <- inverse $ set createNaturalH 1 1 0
	let e = c `multiply` d
	let f = e `multiply` createRotateH 1 (pi / 4)::Matrix
	return f
 このような具合に、Maybeをひたすら重ねていくようにすれば、inverseのたびに失敗処理を書く必要はありません。
カテゴリ [開発魔法][社会問題][経済・知的財産] [トラックバック 0][コメント 0]
<- 前の記事を参照 次の記事を参照 ->

- Blog by yamicha.com -