Task: Vector products






PHP: <?php

class Vector
{
	private $values;

	public function setValues(array $values)
	{
		if (count($values) != 3)
			throw new Exception('Values must contain exactly 3 values');
		foreach ($values as $value)
			if (!is_int($value) && !is_float($value))
				throw new Exception('Value "' . $value . '" has an invalid type');
		$this->values = $values;
	}

	public function getValues()
	{
		if ($this->values == null)
			$this->setValues(array (
					0,
					0,
					0
			));
		return $this->values;
	}

	public function Vector(array $values)
	{
		$this->setValues($values);
	}

	public static function dotProduct(Vector $va, Vector $vb)
	{
		$a = $va->getValues();
		$b = $vb->getValues();
		return ($a[0] * $b[0]) + ($a[1] * $b[1]) + ($a[2] * $b[2]);
	}

	public static function crossProduct(Vector $va, Vector $vb)
	{
		$a = $va->getValues();
		$b = $vb->getValues();
		return new Vector(array (
				($a[1] * $b[2]) - ($a[2] * $b[1]),
				($a[2] * $b[0]) - ($a[0] * $b[2]),
				($a[0] * $b[1]) - ($a[1] * $b[0])
		));
	}

	public static function scalarTripleProduct(Vector $va, Vector $vb, Vector $vc)
	{
		return self::dotProduct($va, self::crossProduct($vb, $vc));
	}

	public static function vectorTrippleProduct(Vector $va, Vector $vb, Vector $vc)
	{
		return self::crossProduct($va, self::crossProduct($vb, $vc));
	}
}

class Program
{

	public function Program()
	{
		$a = array (
				3,
				4,
				5
		);
		$b = array (
				4,
				3,
				5
		);
		$c = array (
				-5,
				-12,
				-13
		);
		$va = new Vector($a);
		$vb = new Vector($b);
		$vc = new Vector($c);

		$result1 = Vector::dotProduct($va, $vb);
		$result2 = Vector::crossProduct($va, $vb)->getValues();
		$result3 = Vector::scalarTripleProduct($va, $vb, $vc);
		$result4 = Vector::vectorTrippleProduct($va, $vb, $vc)->getValues();

		printf("\n");
		printf("A = (%0.2f, %0.2f, %0.2f)\n", $a[0], $a[1], $a[2]);
		printf("B = (%0.2f, %0.2f, %0.2f)\n", $b[0], $b[1], $b[2]);
		printf("C = (%0.2f, %0.2f, %0.2f)\n", $c[0], $c[1], $c[2]);
		printf("\n");
		printf("A · B = %0.2f\n", $result1);
		printf("A × B = (%0.2f, %0.2f, %0.2f)\n", $result2[0], $result2[1], $result2[2]);
		printf("A · (B × C) = %0.2f\n", $result3);
		printf("A × (B × C) =(%0.2f, %0.2f, %0.2f)\n", $result4[0], $result4[1], $result4[2]);
	}
}

new Program();
?>






Ada: with Ada.Text_IO;

procedure Vector is
   type Float_Vector is array (Positive range <>) of Float;
   package Float_IO is new Ada.Text_IO.Float_IO (Float);

   procedure Vector_Put (X : Float_Vector) is
   begin
      Ada.Text_IO.Put ("(");
      for I in X'Range loop
         Float_IO.Put (X (I), Aft => 1, Exp => 0);
         if I /= X'Last then
            Ada.Text_IO.Put (", ");
         end if;
      end loop;
      Ada.Text_IO.Put (")");
   end Vector_Put;

   
   function "*" (Left, Right : Float_Vector) return Float_Vector is
   begin
      if Left'Length /= Right'Length then
         raise Constraint_Error with "vectors of different size in dot product";
      end if;
      if Left'Length /= 3 then
         raise Constraint_Error with "dot product only implemented for R**3";
      end if;
      return Float_Vector'(Left (Left'First + 1) * Right (Right'First + 2) -
                             Left (Left'First + 2) * Right (Right'First + 1),
                           Left (Left'First + 2) * Right (Right'First) -
                             Left (Left'First) * Right (Right'First + 2),
                           Left (Left'First) * Right (Right'First + 1) -
                             Left (Left'First + 1) * Right (Right'First));
   end "*";

   
   function "*" (Left, Right : Float_Vector) return Float is
      Result : Float := 0.0;
      I, J : Positive;
   begin
      if Left'Length /= Right'Length then
         raise Constraint_Error with "vectors of different size in scalar product";
      end if;
      I := Left'First; J := Right'First;
      while I <= Left'Last and then J <= Right'Last loop
         Result := Result + Left (I) * Right (J);
         I := I + 1; J := J + 1;
      end loop;
      return Result;
   end "*";

   
   function "*" (Left : Float_Vector; Right : Float) return Float_Vector is
      Result : Float_Vector (Left'Range);
   begin
      for I in Left'Range loop
         Result (I) := Left (I) * Right;
      end loop;
      return Result;
   end "*";

   A : constant Float_Vector := (3.0, 4.0, 5.0);
   B : constant Float_Vector := (4.0, 3.0, 5.0);
   C : constant Float_Vector := (-5.0, -12.0, -13.0);
begin
   Ada.Text_IO.Put ("A: "); Vector_Put (A); Ada.Text_IO.New_Line;
   Ada.Text_IO.Put ("B: "); Vector_Put (B); Ada.Text_IO.New_Line;
   Ada.Text_IO.Put ("C: "); Vector_Put (C); Ada.Text_IO.New_Line;
   Ada.Text_IO.New_Line;
   Ada.Text_IO.Put ("A dot B = "); Float_IO.Put (A * B, Aft => 1, Exp => 0);
   Ada.Text_IO.New_Line;
   Ada.Text_IO.Put ("A x B = "); Vector_Put (A * B);
   Ada.Text_IO.New_Line;
   Ada.Text_IO.Put ("A dot (B x C) = "); Float_IO.Put (A * (B * C), Aft => 1, Exp => 0);
   Ada.Text_IO.New_Line;
   Ada.Text_IO.Put ("A x (B x C) = "); Vector_Put (A * Float_Vector'(B * C));
   Ada.Text_IO.New_Line;
end Vector;