esercizio1.java

La classe NumeroComplesso presenta una interessante implementazione: la gestione interna permette di utilizzare a seconda dei metodi lo stato più appropriato per effettuare i calcoli. Pertanto vengono memorizzati sia la forma cartesiana che la forma trigonometrica dell'oggetto numero complesso.

La forma cartesiana identifica il numero nelle componenti parte reale e coefficiente della parte complessa.

La forma trigonometrica identifica il numero nel suo modulo o norma e l'anomalia o argomento.

Per scelta l'argomento principale é compreso tra -π e +π.
L'Argomento viene ricavato in base al valore relativo k in modo che Arg(z)=arg(z)+2kπ.

Ulteriori miglioramenti devono essere implementati per mantenere coerente lo stato dell'oggetto e per ritornare lavori compresi sempre tra -π e +π.


Classi: esercizio1.java | NumeroComplesso.java


package corsoDrZito.lez2.es1;

public class esercizio1
{
	public static void main(String[] args)
	{
		esercizio1 app = new esercizio1();
		app.run();
	}

	void run()
	{
		NumeroComplesso a    = new NumeroComplesso(1.0, 0.0);
		NumeroComplesso b    = new NumeroComplesso(0.0, 1.0);
		NumeroComplesso c    = new NumeroComplesso(1.0, Math.PI, 1); // Pi+2Pi
		NumeroComplesso zero = new NumeroComplesso(0.0, 0.0);
		NumeroComplesso unouno = new NumeroComplesso(1.0, 1.0);

		System.out.println( "Parte reale, coefficiente parte immaginaria, modulo, argomento, argomento principale");
		System.out.println( "Re ("+ a +") = "+ a.Re());
		System.out.println( "Im ("+ a +") = "+ a.Im());
		System.out.println( "Ro ("+ a +") = "+ a.Ro());
		System.out.println( "arg("+ a +") = "+ a.arg());
		System.out.println( "Arg("+ c +") = "+ c.Arg());
		System.out.println( "arg("+ c +") = "+ c.arg());

		System.out.println( "\nOperazioni unarie");
		System.out.println( "Coniugato "+ b +" = "+ b.coniugato() );
		System.out.println( "Reciproco "+ unouno +" = "+ unouno.reciproco() );
		System.out.println( "Reciproco "+ unouno +" = "+ unouno.reciproco() );

		System.out.println( "\nOperazioni binarie");
		System.out.println( "Addizione   : "+ a +" + "+ b +" = "+ a.addizione(b) );
		System.out.println( "Sottrazione : "+ a +" - "+ b +" = "+ a.sottrazione(b) );
		System.out.println( "Prodotto    : "+ b +" * "+ c +" = "+ b.prodotto(c) );
		try	{
		System.out.println( "Divisione   : "+ b +" / "+ c +" = "+ b.divisione(c) );
		System.out.println( "Divisione   : "+ a +" / "+ zero +" = "+ a.divisione(zero) );
		} catch (ArithmeticException e) { System.out.println( e ); }

		try {
		System.out.println( "\nOperazioni potenza intera e radice complessa");
		System.out.println( "Potenza     : "+ unouno +" ^ 2 = "+ unouno.potenza(2) );
		System.out.println( "Potenza     : "+ a +" ^ 0 = "+ a.potenza(0) );
		System.out.println( "Potenza     : "+ zero +" ^-3 = "+ zero.potenza(-3) );
		} catch (ArithmeticException e) { System.out.println( e ); }


		NumeroComplesso i = new NumeroComplesso(0.0, 1.0);
		NumeroComplesso[] radici = NumeroComplesso.radice( i , 3 );
		System.out.println( "Radici terze di "+ i);
		for(int k=0; k<radici.length; k++) System.out.println( "radice "+ k +" = "+ radici[k] );

		System.out.println( (radici[2].theta + 2*radici[2].k*Math.PI + Math.IEEEremainder(radici[2].theta + 2*radici[2].k*Math.PI, 2 * Math.PI)) / Math.PI );
	}
}


package corsoDrZito.lez2.es1;

public class NumeroComplesso
{
	double re, im; 		// parte reale e coefficiente parte immaginaria forma cartesiana: z = a + i b
	double ro, theta; 	// modulo e argomento principale forma Trigonometrica: z = ro(cos theta + i sen theta)
						// ro in [0,+oo[  ,  -Pi < theta <= Pi
	int k = 0;			// argomento = theta + 2 k Pi

	boolean inFormaCartesiana;  // stato attuale

	public NumeroComplesso(double re, double im)
	{
		this.re = re;
		this.im = im;
		inFormaCartesiana = true;
		coerenza();
	}

	public NumeroComplesso(double ro, double theta, int k)
	{
		this.ro    = ro;
		this.theta = theta;
		this.k     = k;
		inFormaCartesiana = false;
		coerenza();
	}

	public double Re()
	{
		if(!inFormaCartesiana) return ro * Math.cos( theta );
		return re;
	}

	public double Im()
	{
		if(!inFormaCartesiana) return ro * Math.sin( theta );
		return im;
	}

	public double Ro()
	{
		if(inFormaCartesiana) return Math.sqrt( re*re + im*im );
		return ro;
	}

	public double Arg()
	{
		if(inFormaCartesiana) return Math.atan2( im , re ) + 2.0 * k * Math.PI;
		return theta + 2.0 * k * Math.PI;
	}

	public double arg()
	{
		if(inFormaCartesiana) return Math.atan2( im , re );
		return theta;
	}

	public NumeroComplesso coniugato()
	{
		if(inFormaCartesiana)
			im = -im;
		else
			theta = -theta;

		return this;
	}

	public NumeroComplesso addizione(NumeroComplesso z)
	{
		if(!inFormaCartesiana) coerenza();
		if(!z.inFormaCartesiana) z.coerenza();

		re += z.re;
		im += z.im;

		return this;
	}

	public NumeroComplesso sottrazione(NumeroComplesso z)
	{
		if(!inFormaCartesiana) coerenza();
		if(!z.inFormaCartesiana) z.coerenza();

		re -= z.re;
		im -= z.im;

		return this;
	}

	public NumeroComplesso prodotto(NumeroComplesso z)
	{
		if(inFormaCartesiana)
		{
			if(!z.inFormaCartesiana) z.coerenza();

			double temp;
			temp = re * z.re - im * z.im;
			  im = re * z.im + im * z.re;
			  re = temp;
		}
		else
		{
			if(z.inFormaCartesiana) z.coerenza();

			ro *= z.ro;
			theta += z.theta;
		}
		return this;
	}

	public NumeroComplesso reciproco() throws ArithmeticException
	{
		if(inFormaCartesiana)
		{
			double temp = re * re  + im * im;
			if (temp==0) throw new ArithmeticException("reciproco di zero");
			re /= temp;
			im /= temp;
		}
		else
		{
			if (ro == 0.0) throw new ArithmeticException("reciproco di zero");
			ro = 1.0 / ro;
			theta = - theta;
		}
		return this;
	}

	public NumeroComplesso divisione(NumeroComplesso z) throws ArithmeticException
	{
		if(inFormaCartesiana)
		{
			if(!z.inFormaCartesiana) z.coerenza();

			double temp = z.re * z.re  + z.im * z.im;
			if (temp==0) throw new ArithmeticException("divisione per zero");

			re = ( re * z.re + im * z.im ) / temp;
			im = ( im * z.re - re * z.im ) / temp;
		}
		else
		{
			if (ro == 0.0) throw new ArithmeticException();
			ro /= z.ro;
			theta -= z.theta;
		}
		return this;
	}

	public NumeroComplesso potenza(int exp) throws ArithmeticException
	{
		if(inFormaCartesiana) coerenza();

		if ((ro==0.0)&&(exp<=0)) throw new ArithmeticException("potenza di zero con esponente negativo");
		ro = Math.pow(ro, exp);
		theta *= exp;
		//k = exp;

		return this;
	}

	public static NumeroComplesso[] radice(NumeroComplesso w, int n) throws ArithmeticException
	{
		if(n<=0) throw new ArithmeticException("radice con esponente negativo o nullo");

		NumeroComplesso[] radici = new NumeroComplesso[n];

		if(w.inFormaCartesiana) w.coerenza();

		double ro = Math.pow(w.ro, 1.0d / n);

		for(int i=0; i<n; i++)
			radici[i] = new NumeroComplesso( ro, (w.theta + 2 * i * Math.PI)/n, w.k);
		return radici;
	}

	public static NumeroComplesso[] radice2(NumeroComplesso w, int n) throws ArithmeticException
	{
		if(n<=0) throw new ArithmeticException("radice con esponente negativo o nullo");

		NumeroComplesso[] radici = new NumeroComplesso[n];

		if(w.inFormaCartesiana) w.coerenza();

		double ro = Math.pow(w.ro, 1.0d / n);

		for(int i=0; i<n; i++)
		{
			double theta = (w.theta + 2 * i * Math.PI)/n;
			double remainder = Math.IEEEremainder( theta, 2*Math.PI );
			int k = (int)((theta + remainder) / Math.PI);
			radici[i] = new NumeroComplesso( ro, remainder, k);
		}
		return radici;
	}


	/**
		rende coerente lo stato interno settando le variabili relative alla forma cartesiana o alla forma trigonometrica
	*/
	private void coerenza()
	{
		if(inFormaCartesiana)
		{
			inFormaCartesiana = false;
			ro = Math.sqrt( re * re + im * im );
			if (ro == 0.0) theta = 0.0; // maybe NaN?
			else theta = Math.atan2( im , re );
		}
		else
		{
			inFormaCartesiana = true;
			re = ro * Math.cos( theta );
			im = ro * Math.sin( theta );
		}
	}

	public String toString()
	{
		if (inFormaCartesiana) return ""+ re +((im>=0.0)? "+" : "")+ im +"j";
		else
		{
			String k2pi = (k!=0 ? "+"+2*k+"Pi" : "");
			return ""+ ro +" ( cos "+ theta + k2pi +" + j sen "+ theta + k2pi +")";
		}
	}
}