<?

class m_vector {
	
	/*private $evaluation;
	
	public function __construct($evaluation) {
		$this->evaluation = $evaluation;
	}*/
	
	public function compare_vectors($u, $v) {
		/*if($u[0] == $v[0] && $u[1] == $v[1]) {
			return true;
		}*/
		if($u->length == $v->length) {
			foreach($u as $index => $u_value) {
				if($u_value != $v[$index]) {
					return false;
				}
			}
			return true;
		}
		return false;
	}

	/*public function angle_between_vectors($u, $v) {
		if($this->compare_vectors($u, $v)) {
			return 0;
		}
		$dot = $this->dot_product($u, $v);
		$u_distance = $this->vector_distance($u);
		$v_distance = $this->vector_distance($v);
		$division = $this->evaluation->add_total($u_distance, $v_distance);//$u_distance + $v_distance;
		$result = $this->evaluation->execute_divide($dot, $division);//$dot / $division;
		$result = $math->acos($this->evaluation->quick_fraction($result));
		$result = $this->multiply_total($result, $this->evaluation->whole_common('57.2957795')); 
		return $result;
	}*/

	public function angle_between_vectors($u, $v) {
		/*if($this->compare_vectors($u, $v)) {
			return 0;
		}*/
		if($u == $v) {
			return 0;
		}
		$dot = $this->dot_product($u, $v);
		$u_distance = $this->length_value($u);
		$v_distance = $this->length_value($v);
		$division = $u_distance + $v_distance;
		$result = $dot / $division;
		$result = $math->acos($result);
		/*$result = $this->multiply_total($result, $this->evaluation->whole_common('57.2957795'));*/ 
		return $result;
	}

	/*public function flip_vector($u) {
		$vector = [[...$u[0]], $this->evaluation->negative_value($u[1])];
		return $vector;
	}

	public function flip_x($u) {
		$vector = [$this->evaluation->negative_value($u[0]), [...$u[1]]];
		return $vector;
	}*/

	public function reverse_vector($v) {
		/*$u = [$this->evaluation->negative_value($v[0]), $this->evaluation->negative_value($v[1])];
		return $u;*/
		$u = [];
		foreach($v as $v_value) {
			$u[] = -$v_value;/*$this->evaluation->negative_value($v_value);*/
		}
		return $u;
	}

	/*public function reset_vector_length($point, $length) {
		$initial_length = $this->vector_distance($point, [0,0]);
		$fraction = $this->evaluation->execute_divide($length, $initial_length);
		$new_point = $this->reset_distance($point, $fraction);
		$new_distance = $this->vector_distance($new_point, [0,0]);
		return $new_point;
	}

	public function dot_product($u, $v) {
		return $this->add($this->evaluation->multiply_total($u[0], $v[0]), $this->evaluation->multiply_total($u[1], $v[1]));
	}*/
	
	/*public function projection($u, $v) {
		$division = $this->evaluation->execute_power_whole($this->distance($v[0], $v[1]), 2);
		if($division['value'] == 0 && $this->evaluation->fraction_values($division['remainder'])[0] == 0) {
			return 0;
		}
		$vector = [[...$v[0]], [...$v[1]]];
		$mult = $this->evaluation->execute_divide($this->dot_product($u, $v), $division);
		$vector[0] = $this->evaluation->multiply_total($vector[0], $mult);
		$vector[1] = $this->evaluation->multiply_total($vector[1], $mult);
		$vector = $this->shorten_vector($vector);
		return $vector;
	}
	
	public function vector_distance($u, $v=[['value' => 0, 'remainder' => '0/1'], ['value' => '0', 'remainder' => '0/1']]) {
		return $this->distance($u[0], $u[1], $v[0], $v[1]);
	}
	
	public function vector_sum($u, $value) {
		$vector = [[...$u[0]], [...$u[1]]];
		$vector[0] = $this->evaluation->add_total($vector[0], $value);
		$vector[1] = $this->evaluation->add_total($vector[1], $value);
		$vector = $this->shorten_vector($vector);
		return $vector;
	}*/
	
	public function add_vector($u, $v) {
		$vector = [];
		if($u->length == $v->length) {
			foreach($u as $index => $u_value) {
				$vector[] = $v[$index]+$u_value;
			}
		}
		return $vector;
	}
	
	public function multiply_vector($u, $v) {
		$vector = [];
		if($u->length == $v->length) {
			foreach($u as $index => $u_value) {
				$vector[] = $v[$index]*$u_value;
			}
		}
		return $vector;
	}
	
	/*public function distance($x_from, $y_from, $x_to=['value' => 0, 'remainder' => '0/1'], $y_to=['value' => 0, 'remainder' => '0/1']) {
		$term_a = $this->evaluation->subtract_total($x_from, $x_to);
		$term_a = $this->evaluation->execute_power_whole($term_a, ['value' => '2', 'remainder' => '0/1']);
		
		$term_b = $this->evaluation->subtract_total($y_from, $y_to);
		$term_b = $this->evaluation->execute_power_whole($term_b, ['value' => '2', 'remainder' => '0/1']);
		
		$total_term = $this->evaluation->add_total($term_a, $term_b);
		$value = $this->evaluation->execute_power($total_term, 2);
		
		return $value;
	}*/
	
	public function length_value($u, $v=NULL, $set_index=(-1), $linear=false) {
		if($v == NULL) {
			$v = [];
			foreach($u as $u_item) {
				$v[] = 0;
			}
		}
		$total_term = 0;

		/*debug*/
		/*$set_index = (-1);*/

		foreach($u as $index => $u_value) {
			if($set_index == (-1) || $set_index == $index) {
				$term_value = $u_value - $v[$index];
				$term_value = $term_value * $term_value;/*$math->pow($term_value, 2);*/

				$total_term = $total_term + $term_value;
			}
		}

		if($linear) {
			return $total_term;
		}

		$value = $math->pow($math->abs($total_term), 1/2);
		return $value;
	}

	public function normalize_linear($v, $skip=false) {
		/*return $v;*/
		/*return $v;*/
		/*$length = $this->length_value($v);
		if($length <= 0) {
			return $v;
		}
		$vector = [];
		foreach($v as $index => $v_value) {
			$vector[] = $v_value * 1 / $length;
		}
		return $vector;*/

		$min_value = (-1);
		$max_value = (-1);

		foreach($v as $value) {
			if($value < $min_value || $min_value == (-1)) {
				$min_value = $value;
			}
			if($value > $max_value || $max_value == (-1)) {
				$max_value = $value;
			}
		}

		$range = $max_value - $min_value;

		foreach($v as $key => $value) {
			if($range != 0) {
				$v[$key] = ($value - $min_value) / $range;
			}
		}

		return $v;
	}

	public function normalize($v, $skip=false) {
		/*return $v;*/
		/*return $v;*/
		$length = $this->length_value($v);
		if($length <= 0) {
			return $v;
		}
		$vector = [];
		foreach($v as $index => $v_value) {
			$vector[] = $v_value * 1 / $length;
		}
		return $vector;
	}
	
	public function normalize_vector($v, $skip=false) { 
		/*fjarlageja comments?*/
		/*if(!$skip) {
		}*/

		$length = $this->length_value($v);
		if($length <= 0) {
			return $v;
		}
		$vector = [];
		foreach($v as $index => $v_value) {
			$vector[] = $v_value * 1 / $length;
		}
		return $vector;
	}
	
	public function subtract_vector($u, $v) {
		$vector = [];
		if($u->length == $v->length) {
			foreach($u as $index => $u_value) {
				$vector[] = $v[$index] - $u_value;
			}
		}
		return $vector;
	}

	/*public function sum_vector($u, $v) {
		$vector = [[...$u[0]], [...$u[1]]];
		$vector[0] = $this->evaluation->add_total($vector[0], $v[0]);
		$vector[1] = $this->evaluation->add_total($vector[1], $v[1]);
		$vector = $this->shorten_vector($vector);
		return $vector;
	}*/
	
	public function stretch_vector($u, $unit_value) {
		$vector = [];
		foreach($u as $index => $u_value) {
			$vector[] = $unit_value * $u_value;
		}
		return $vector;

	}

	
	public function denormalize_vertically($vector) {
		$max_value = (-1);
		$min_value = (-1);
		foreach($vector as $index => $value) {
			if($max_value == (-1) || $value > $max_value) {
				$max_value = $value;
			}
			if($min_value == (-1) || $value < $min_value) {
				$min_value = $value;
			}
		}
		/*$object->log($object->toJSON([$min_value, $max_value]));*/
		if($max_value > 0 && $min_value < $max_value) {
			$divider = $max_value - $min_value;
			/*$object->log('divider: '.$divider);*/
			foreach($vector as $index => $value) {
				/*if($index < 5) {*/
					if($divider > 0) {
						/*$object->log($value);*/
						$value = $value - $min_value;
						/*if($value == 0) {
							$value = ;
						}*/

						/*$object->log($object->toJSON([$value, $divider]));*/

						$vector[$index] = (1/10000) + ($value / ($divider));
					}
				/*}*/
			}
		}
		/*$object->log($object->toJSON(['denormalize', $max_value, $min_value, $vector]));*/
	}

	public function reflection($u, $v) {
		$proj = $this->projection($u, $v);
		$proj = $this->stretch_vector($proj, 2);
		$position = $this->subtract_vector($u, $proj);
		/*$position = $this->add_vector($position, $proj);*/

		return $position;
	}

	public function projection($u, $v) {
		$dot_numerator = $this->dot_product($u, $v);
		$dot_denominator = $this->dot_product($v, $v);

		$multiply_value = $dot_numerator / $dot_denominator;

		return $this->stretch_vector($v, $multiply_value);
	}
	
	public function dot_product($u, $v) {
		/*return $this->add($this->evaluation->multiply_total($u[0], $v[0]), $this->evaluation->multiply_total($u[1], $v[1]));*/
		$addition_value = 0;
		foreach($u as $index => $u_value) {
			$v_value = $v[$index];

			$addition_value = $addition_value + ($u_value * $v_value);
		}

		return $addition_value;
	}
	
	/*public function reflection($d, $n) {
		$n = [[...$n[0]], [...$n[1]]];
		$n = $this->normalize_vector($n);
		$dot = $this->dot_product($d, $n);
		$dot = $this->evaluation->multiply_total(['value' => 2, 'remainder' => '0/1'], $dot);
		$stretch = $this->stretch_vector($n, $dot);
		$subtract = $this->subtract_vector($d, $stretch);
		$subtract = $this->shorten_vector($subtract);
		return $subtract;
	}
	
	public function rotate($u, $clockwise=true) {
		$v = [[...$u[1]], $this->evaluation->negative_value($u[0])];
		return $v;
	}*/
	
	/*public function shorten_vector($vector) {
		$result = [];
		foreach($vector as $index => $value) {
			$value = [...$value];
			$value['remainder'] = $this->evaluation->execute_shorten_fraction($value['remainder']);
			$result[] = $value;
		}
		return $result;
	}*/
}

?>