美文网首页
(一)复数运算

(一)复数运算

作者: 石榴楠 | 来源:发表于2018-12-17 17:50 被阅读0次

工作之余,突然想用java写一套数值计算的算法套件,权当练手。当然要包括后台和前台,先整后台,具体算法部分。前台考虑web端做个类似“计算器”的东东,等有空再说吧。

算法

首先第一天,先来个复数运算。这其中的数学原理就先略过了,当然如果有需要,以后再补充。先来一段源码先:


package com.mysite.algorithm.model;

import lombok.Data;

import lombok.ToString;

import java.util.*;

import java.math.*;

@Data

public class Complex {

private Doublereal =0.0;

private Doubleimaginary =0.0;

private Doubleeps =0.0;//默认精度

    public Complex(Double r, Double i){

this.real = r;

this.imaginary = i;

}

public Complex(Complex c){

this.real = c.getReal();

this.imaginary = c.getImaginary();

}


public Boolean Equals(Object o){

Complex c = (Complex)o;

if(c ==null)return false;

return Math.abs(this.real - c.getReal()) <=this.eps &&

Math.abs(this.imaginary - c.getImaginary()) <=this.eps;

}

public Complex Add(Complex c){

Double r =this.real + c.getReal();

Double i =this.imaginary + c.getImaginary();

return new Complex(r,i);

}

public Complex Subtract(Complex c){

Double r =this.real - c.getReal();

Double i =this.imaginary - c.getImaginary();

return new Complex(r,i);

}

public Complex Multiply(Complex c){

Double r =this.real * c.getReal() -this.imaginary * c.getImaginary();

Double i =this.real * c.getImaginary() +this.imaginary * c.getReal();

return new Complex(r,i);

}

public Complex Devide(Complex c){

Double e,f,x,y;

if(Math.abs(c.getReal()) >= Math.abs(c.getImaginary())){

e = c.getImaginary() / c.getReal();

f= c.getReal() + e * c.getImaginary();

x = (this.real +this.imaginary * e)/f;

y = (this.imaginary -this.real * e)/f;

}else{

e= c.getReal() / c.getImaginary();

f = c.getImaginary()+ e * c.getReal();

x = (this.real * e +this.imaginary)/f;

y = (this.imaginary *e -this.real)/f;

}

return new Complex(x,y);

}

public Double Abs(){

return Math.sqrt(this.real *this.real +this.imaginary *this.imaginary);

}

// 返回共轭复数

    public Complex Conjuagte(){

return new Complex(this.real ,0.0 -this.imaginary);

}

// 求复数的N次方根

    public List Root(Integer n){

List ret =new ArrayList<>();

if(n <1)return null;

Double q = Math.atan2(this.imaginary,this.real);

Double r = Math.sqrt(this.real*this.real +this.imaginary *this.imaginary);

if(r!=0){

r = (1.0 /n) * Math.log(r);

r = Math.exp(r);

}

for(Integer k =0;k <= n-1; k++){

Double t = (2.0 *k*Math.PI + q)/n;

Complex complex =new Complex(r*Math.cos(t), r* Math.sin(t));

ret.add(complex);

}

return ret;

}

// 计算复数的实幂指数

    public Complex Pow(Double p){

Double r,t;

if(this.imaginary ==0 &&this.real ==0)return new Complex(0.0,0.0);

if(this.real ==0){

if(this.imaginary >0){

t = Math.PI /2;

}else {

t = -Math.PI/2;

}

}

else {

if(this.real >0){

t = Math.atan2(this.imaginary,this.real);

}

else{

if(this.imaginary >0){

t = Math.atan2(this.imaginary,this.real) + Math.PI;

}else{

t = Math.atan2(this.imaginary,this.real) - Math.PI;

}

}

}

r = Math.exp(p * Math.log(Math.sqrt(this.real *this.real +this.imaginary *this.imaginary)));

return new Complex(r* Math.cos(p * t), r* Math.sin(p * t));

}

// 计算复数的复幂指数

    public Complex Pow(Complex p, Integer n){

Double r,s,u,v;

if(this.real ==0){

if(this.imaginary ==0)return new Complex(0.0,0.0);

s = Math.PI /2 * (Math.abs(this.imaginary)/this.imaginary +4*n);

}else{

s =2 * Math.PI * n + Math.atan2(this.imaginary,this.real);

if(this.real <0){

s =this.imaginary >0 ? s + Math.PI : s - Math.PI;

}

}

r =0.5 * Math.log(this.real *this.real +this.imaginary *this.imaginary);

v = p.getReal() * r + p.getImaginary() * s;

u = Math.exp(p.getReal() * r - p.getImaginary() * s);

return new Complex(u * Math.cos(v), u * Math.sin(v));

}

// 求复数的自然对数

    public Complex Log(){

Double p = Math.log(Math.log(Math.sqrt(this.real *this.real +this.imaginary *this.imaginary)));

return new Complex(p, Math.atan2(this.imaginary,this.real));

}

// 求复数的正弦

    public Complex Sin(){

Double p[] = sincos();

Double x = p[0], y = p[1];

return new Complex( x * Math.sin(this.real), y * Math.cos(this.real));

}

// 求复数的余弦

    public Complex Cos(){

Double p[] = sincos();

Double x = p[0], y = p[1];

return new Complex( x * Math.cos(this.real), -y * Math.sin(this.real));

}

private Double[] sincos(){

Integer i;

Double x,y ,y1,br =0.0, b1 =0.0, b2 =0.0;

//切比雪夫公式的常数系数

        Double c[] =new Double[6];

c[0] =1.13031820798597;

c[1] =0.04433684984866;

c[2] =0.00054292631191;

c[3] =0.00000319843646;

c[4] =0.00000001103607;

c[5] =0.00000000002498;

y1 = Math.exp(this.imaginary);

x =0.5 * (y1 +1/y1);

if(Math.abs(this.imaginary) >=1){

y =0.5 * (y1 -1/y1);

}else{

y1 =2 * (2 *this.imaginary *this.imaginary -1);

for(i =5;i >=0;--i){

br = y1 * b1 - b2 - c[i];

if(i !=0){

b2 = b1;

b1 = br;

}

}

y =this.imaginary * (br - b1);

}

Double ret[] =new Double[2];

ret[0] = x;

ret[1] = y;

return  ret;

}

// 计算复数的正切

    public Complex Tan(){

return Sin().Devide(Cos());

}

}

验证

包括了基本运算法则加减乘除还有幂,方根等,基本够用了。那么如何验证我们的代码是否正确呢?这个时候可以借助科学计算领域的大神python,同样的算式看看两边计算的结果是否相等就可以了。
测试代码如下:

 private static void TestComplex(){
        Complex a = new Complex(2.0,4.0);
        Complex b = new Complex(3.0,-5.0);

        System.out.println(a.ToString());
        System.out.println("a+b:" + a.Add(b));
        System.out.println("a-b:" + a.Subtract(b));
        System.out.println("a*b:" + a.Multiply(b));
        System.out.println("a/b:" + a.Devide(b));

        System.out.println("sin(a):" + a.Sin());
        System.out.println("cos(a):" + a.Cos());
        System.out.println("sqrt(a)" + a.Root(2));

    }

运行结果如下:

a+b:Complex(real=5.0, imaginary=-1.0, eps=0.0)
a-b:Complex(real=-1.0, imaginary=9.0, eps=0.0)
a*b:Complex(real=26.0, imaginary=2.0, eps=0.0)
a/b:Complex(real=-0.4117647058823529, imaginary=0.6470588235294118, eps=0.0)
sin(a):Complex(real=24.83130584894638, imaginary=-11.356612711218173, eps=0.0)
cos(a):Complex(real=-11.36423470640106, imaginary=-24.814651485634183, eps=0.0)
sqrt(a)[Complex(real=1.7989074399478673, imaginary=1.1117859405028423, eps=0.0), Complex(real=-1.7989074399478673, imaginary=-1.111785940502842, eps=0.0)]

用python进行同样的计算,结果如下:

import cmath
 a = complex(2,4)
 b = 3-5j
 a+b
(5-1j)
 a-b
(-1+9j)
 a*b
(26+2j)
 a/b
(-0.4117647058823529+0.6470588235294118j)
cmath.sin(a)
(24.83130584894638-11.356612711218174j)
 cmath.cos(a)
(-11.36423470640106-24.814651485634187j)
cmath.sqrt(a)
(1.7989074399478673+1.1117859405028423j)
···
可见二者的结果是一致的,我们的算法正确(其他情况请自行验证)。好了,今天就到此为止了。

相关文章

  • 基于C++的操作符重载实现编译多态——复数的加法运算

    操作符重载实现编译多态——复数的加法运算,VC++基础级的复数运算例子,主要是使用重载的+运算符实现复数与复数的相...

  • (一)复数运算

    工作之余,突然想用java写一套数值计算的算法套件,权当练手。当然要包括后台和前台,先整后台,具体算法部分。前台考...

  • 复数运算

  • 算法训练 P1103

    编程实现两个复数的运算。设有两个复数 和 ,则他们的运算公式为: 要求:(1)定义一个结构体类型来描述复数。(2)...

  • 复数、欧拉公式和复指数信号

    一、复数定义 二、复数运算与几何意义 复数可以表示为复平面的向量,其中a为实轴坐标,b为虚轴坐标。 对任意两个复数...

  • python 数字

    整数 复数 浮点数 进制表示 进制转换 运算

  • 复数的基本概念

    复数域 实数x与y分别称为复数z的实部和虚部,记作虚部为零的复数就可以看作实数,虚部不为零的复数称为虚数复数运算 ...

  • 2019-07-24

    一、复数(https://zhuanlan.zhihu.com/p/46574502) 二、取整运算、有效小数、有...

  • 基本算术模块

    一、math模块和cmath模块 1.math模块支持整数、浮点数这些数值型的运算。cmath模块支持复数运算如下...

  • Mathematica常用规则

    一、基本运算 四则运算中只能用圆括号改变运算顺序 四种内置数据类型:整数、有理数、实数、复数 常用常数: 常用常数...

网友评论

      本文标题:(一)复数运算

      本文链接:https://www.haomeiwen.com/subject/dvmckqtx.html