/* Copyright 2010 Aaron J. Radke Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package cc.drx object Complex{ def angle(a:Angle):Complex = new Complex(a.cos, a.sin) //TODO use apply instead of polar for a more type inference based api def angle(mag:Double,a:Angle):Complex = new Complex(a.cos*mag, a.sin*mag) val i = new Complex(0d,1d) val r = new Complex(1d,0d) } case class Complex(r:Double,i:Double){ def toVec = Vec(r,i) //---complex ops def +(b:Complex):Complex = Complex(r+b.r, i+b.i) def -(b:Complex):Complex = Complex(r-b.r, i-b.i) def *(b:Complex):Complex = Complex(r*b.r - i*b.i, i*b.r + r*b.i) def /(b:Complex):Complex = if(b.r == 0 && b.i == 0) Complex(0,0)/*TODO throw error*/ else { val den = b.normSq val rnum = r*b.r + i*b.i val inum = i*b.r - r*b.i Complex(rnum/den, inum/den) } //---scalar ops /**negate the vector*/ def unary_- :Complex = new Complex(-r , -i) //TODO should we supply an implicit double to complex?? it should promote just like int, goes to double, double goes to complex def +(v:Double):Complex = Complex(r+v, i) def -(v:Double):Complex = Complex(r-v, i) def *(s:Double):Complex = new Complex(r*s, i*s) def /(s:Double):Complex = new Complex(r/s, i/s) 2017-07-30("use normSq instead", "0.2.13") lazy val norm2:Double = normSq def normSq:Double = r*r + i*i def norm:Double = normSq.sqrt def abs:Double = norm def conj = Complex(r,-i) def sqrt:Complex = if(i == 0){ if(r < 0) Complex(0,r.abs.sqrt) else Complex(r.sqrt,0) } else { val d = norm/2 val a = r/2 val gamma = (d + a).sqrt val delta = i.sgn * (d - a).sqrt Complex(gamma,delta) } def exp:Complex = Complex(i.cos, i.sin) * r.exp def arg:Double = i atan2 r def log:Complex= Complex(r.log, arg) def phase:Angle = Angle(arg) def dist(that:Complex):Double = (that-this).norm }