Complex numbers

  • Thread starter Thread starter Jon Harrop
  • Start date Start date
J

Jon Harrop

I can't seem to find an implementation of complex numbers in the C# standard
library. Is there one?
 
Jon,

No, there is not. You will have to implement it yourself, or use a
third-party implementation.
 
Jon,

No, there is not. You will have to implement it yourself, or use a
third-party implementation.

And I don't think it would be all that hard to implement. All you need
is a class with two properties, real part and imaginary part, and then
a series of methods to do things like add, suntract, etc.
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)






I can't seem to find an implementation of complex numbers in the C#
standard
library. Is there one?

- Show quoted text -
 
All you need is a class with two properties, real part and imaginary part
IMO, this would be one of the (few) occasions when a struct
(immutable) would be in order. The painful part here is having to
choose a type for the 2 components (or duplicate the code) - since
unfortunately generics do not allow you to efficiently use operators
such as *, +, - (and hence you can't do Complex<T> for T in {int,
decimal, etc...})

Marc
 
I would use a struct here, not a class.

Nonetheless, you are right: it wouldn't be hard to implement.
 
And I don't think it would be all that hard to implement. All you need
is a class with two properties, real part and imaginary part, and then
a series of methods to do things like add, suntract, etc.

Ugh. That really sucks. I appreciate that it is faily easy to implement
yourself but I'd really expect to see complex numbers in a modern
language...

If you want to be accurate, the implementation isn't actually that
straightforward either. Check out these definitions from the OCaml standard
library, for example:

let div x y =
if abs_float y.re >= abs_float y.im then
let r = y.im /. y.re in
let d = y.re +. r *. y.im in
{ re = (x.re +. r *. x.im) /. d;
im = (x.im -. r *. x.re) /. d }
else
let r = y.re /. y.im in
let d = y.im +. r *. y.re in
{ re = (r *. x.re +. x.im) /. d;
im = (r *. x.im -. x.re) /. d }

let norm x =
(* Watch out for overflow in computing re^2 + im^2 *)
let r = abs_float x.re and i = abs_float x.im in
if r = 0.0 then i
else if i = 0.0 then r
else if r >= i then
let q = i /. r in r *. sqrt(1.0 +. q *. q)
else
let q = r /. i in i *. sqrt(1.0 +. q *. q)

let sqrt x =
if x.re = 0.0 && x.im = 0.0 then { re = 0.0; im = 0.0 }
else begin
let r = abs_float x.re and i = abs_float x.im in
let w =
if r >= i then begin
let q = i /. r in
sqrt(r) *. sqrt(0.5 *. (1.0 +. sqrt(1.0 +. q *. q)))
end else begin
let q = r /. i in
sqrt(i) *. sqrt(0.5 *. (q +. sqrt(1.0 +. q *. q)))
end in
if x.re >= 0.0
then { re = w; im = 0.5 *. x.im /. w }
else { re = 0.5 *. i /. w; im = if x.im >= 0.0 then w else -. w }
end
 
Jon Harrop said:
Yes. I've timed both on a simple all-n FFT implementation and using a struct
is >3x faster.

Unless performance is absolutely critical (which it may be of course) I
wouldn't use it as a reason to choose a class over a struct or vice
versa. The reason for making it a struct is that it's a natural value
type in the same way that int and double are.
 
Ugh. That really sucks. I appreciate that it is faily easy to implement
yourself but I'd really expect to see complex numbers in a modern
language...

That would be an unrealistic expectation. Microsoft isn't involved in
numerical computing, outside of MS Research. Also, neither C# nor
Visual Basic have any ancestry or relationship (C, C++, Java, Basic
dialects) with built-in complex numbers -- unless you count Fortran.
It's just not a requirement for the business users MS is targeting.
 
Ugh. That really sucks. I appreciate that it is faily easy to implement
yourself but I'd really expect to see complex numbers in a modern
language...

If you want to be accurate, the implementation isn't actually that
straightforward either. Check out these definitions from the OCaml standard
library, for example:

let div x y =
if abs_float y.re >= abs_float y.im then
let r = y.im /. y.re in
let d = y.re +. r *. y.im in
{ re = (x.re +. r *. x.im) /. d;
im = (x.im -. r *. x.re) /. d }
else
let r = y.re /. y.im in
let d = y.im +. r *. y.re in
{ re = (r *. x.re +. x.im) /. d;
im = (r *. x.im -. x.re) /. d }

let norm x =
(* Watch out for overflow in computing re^2 + im^2 *)
let r = abs_float x.re and i = abs_float x.im in
if r = 0.0 then i
else if i = 0.0 then r
else if r >= i then
let q = i /. r in r *. sqrt(1.0 +. q *. q)
else
let q = r /. i in i *. sqrt(1.0 +. q *. q)

let sqrt x =
if x.re = 0.0 && x.im = 0.0 then { re = 0.0; im = 0.0 }
else begin
let r = abs_float x.re and i = abs_float x.im in
let w =
if r >= i then begin
let q = i /. r in
sqrt(r) *. sqrt(0.5 *. (1.0 +. sqrt(1.0 +. q *. q)))
end else begin
let q = r /. i in
sqrt(i) *. sqrt(0.5 *. (q +. sqrt(1.0 +. q *. q)))
end in
if x.re >= 0.0
then { re = w; im = 0.5 *. x.im /. w }
else { re = 0.5 *. i /. w; im = if x.im >= 0.0 then w else -. w }
end

OK... maybe a caveat is in order. :-)

It would be relatively easy to implement a basic complex number type
yourself.

To get all of the boundary cases right, though, including avoiding
overflows when very close to the limits of what various types can
hold, and handling other odd situations... well, that would require
some serious study of numerical computing. (I don't count myself as an
expert... let's just say that I've taken enough courses to know what
it is that I don't know....)

So, if you're not going to push the limits, then it's probably pretty
easy to cobble something together. If, on the other hand, you need to
do some heavy-duty calculations that could involve values within an
order of magnitude of what the base type can handle, well then you're
probably better off looking for a commercial package, or something
developed by someone with a deep knowledge of numerical analysis.
 
If I were to implement complex numbers myself, or via a third party, would it work with normal
operators (eg * / + -)?


I can't seem to find an implementation of complex numbers in the C# standard
library. Is there one?
 
Doesn't C++ have complex numbers as standard? If so, C++ is sounding more attractive for a programme
I have to write soon.

Ugh. That really sucks. I appreciate that it is faily easy to implement
yourself but I'd really expect to see complex numbers in a modern
language...

That would be an unrealistic expectation. Microsoft isn't involved in
numerical computing, outside of MS Research. Also, neither C# nor
Visual Basic have any ancestry or relationship (C, C++, Java, Basic
dialects) with built-in complex numbers -- unless you count Fortran.
It's just not a requirement for the business users MS is targeting.
 
Doesn't C++ have complex numbers as standard? If so, C++ is sounding more attractive for a programme
I have to write soon.

Hey, you're right -- the STL defines a template class for complex
numbers. I wasn't aware of that.
 
Jay said:
If I were to implement complex numbers myself, or via a third party, would
it work with normal
operators (eg * / + -)?
If the type is implemented to do so, yes. C# supports operator overloading.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top