Dot product

From Rosetta Code
Task
Dot product
You are encouraged to solve this task according to the task description, using any language you may know.

Create a function/use an in-built function, to compute the dot product, also known as the scalar product of two vectors. If possible, make the vectors of arbitrary length.

As an example, compute the dot product of the vectors [1, 3, -5] and [4, -2, -1].

If implementing the dot product of two vectors directly, each vector must be the same length; multiply corresponding terms from each vector then sum the results to produce the answer.

ActionScript

<lang ActionScript>function dotProduct(v1:Vector.<Number>, v2:Vector.<Number>):Number { if(v1.length != v2.length) return NaN; var sum:Number = 0; for(var i:uint = 0; i < v1.length; i++) sum += v1[i]*v2[i]; return sum; } trace(dotProduct(Vector.<Number>([1,3,-5]),Vector.<Number>([4,-2,-1])));</lang>

Ada

<lang Ada> with Ada.Text_IO; use Ada.Text_IO; procedure dot_product is type vect is array(Positive range <>) of Integer; v1 : vect := (1,3,-5); v2 : vect := (4,-2,-1);

function dotprod(a: vect; b: vect) return Integer is sum : Integer := 0; begin if not (a'Length=b'Length) then raise Constraint_Error; end if; for p in a'Range loop sum := sum + a(p)*b(p); end loop; return sum; end dotprod;

begin put_line(Integer'Image(dotprod(v1,v2))); end dot_product; </lang> Output:

3

ALGOL 68

Translation of: C++
Works with: ALGOL 68 version Standard - with prelude inserted manually
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386

<lang algol68>MODE DOTFIELD = REAL; MODE DOTVEC = [1:0]DOTFIELD;

  1. The "Spread Sheet" way of doing a dot product:
 o Assume bounds are equal, and start at 1 
 o Ignore round off error

PRIO SSDOT = 7; OP SSDOT = (DOTVEC a,b)DOTFIELD: (

 DOTFIELD sum := 0;
 FOR i TO UPB a DO sum +:= a[i]*b[i] OD;
 sum

);

  1. An improved dot-product version:
 o Handles sparse vectors
 o Improves summation by gathering round off error
   with no additional multiplication - or LONG - operations.

OP * = (DOTVEC a,b)DOTFIELD: (

 DOTFIELD sum := 0, round off error:= 0;
 FOR i
  1. Assume bounds may not be equal, empty members are zero (sparse) #
   FROM LWB (LWB a > LWB b | a | b )
   TO UPB (UPB a < UPB b | a | b ) 
 DO
   DOTFIELD org = sum, prod = a[i]*b[i];
   sum +:= prod;
   round off error +:= sum - org - prod
 OD;
 sum - round off error

);

  1. Test: #

DOTVEC a=(1,3,-5), b=(4,-2,-1);

print(("a SSDOT b = ",fixed(a SSDOT b,0,real width), new line)); print(("a * b = ",fixed(a * b,0,real width), new line))</lang> Output:

a SSDOT b = 3.000000000000000
a   *   b = 3.000000000000000

AutoHotkey

<lang AutoHotkey>Vet1 := "1,3,-5" Vet2 := "4 , -2 , -1" MsgBox % DotProduct( Vet1 , Vet2 )

---------------------------

DotProduct( VectorA , VectorB ) {

 Sum := 0
 StringSplit, ArrayA, VectorA, `,, %A_Space%
 StringSplit, ArrayB, VectorB, `,, %A_Space%
 If ( ArrayA0 <> ArrayB0 )
   Return ERROR
 While ( A_Index <= ArrayA0 )
   Sum += ArrayA%A_Index% * ArrayB%A_Index%
 Return Sum

}</lang>

C

<lang c>#include <stdio.h>

  1. include <stdlib.h>

int dot_product(int *, int *, size_t);

int main(void) {

       int a[3] = {1, 3, -5};
       int b[3] = {4, -2, -1};
       printf("%d\n", dot_product(a, b, sizeof(a) / sizeof(a[0])));
       return EXIT_SUCCESS;

}

int dot_product(int *a, int *b, size_t n) {

       int sum = 0;
       size_t i;
       for (i = 0; i < n; i++) {
               sum += a[i] * b[i];
       }
       return sum;

}</lang> Output: <lang>3</lang>

C_sharp

<lang csharp> static void Main(string[] args) { Console.WriteLine(DotProduct(new decimal[] { 1, 3, -5 }, new decimal[] { 4, -2, -1 })); Console.Read(); }

private static decimal DotProduct(decimal[] vec1, decimal[] vec2) { if (vec1 == null) return 0;

if (vec2 == null) return 0;

if (vec1.Length != vec2.Length) return 0;

decimal tVal = 0; for (int x = 0; x < vec1.Length; x++) { tVal += vec1[x] * vec2[x]; }

return tVal; } </lang> Output: <lang>3</lang>

C++

<lang cpp>#include <iostream>

  1. include <numeric>

int main() {

   int a[] = { 1, 3, -5 };
   int b[] = { 4, -2, -1 };
   std::cout << std::inner_product(a, a + sizeof(a) / sizeof(a[0]), b, 0) << std::endl;
   return 0;

}</lang> Output: <lang>3</lang>

Clojure

Works with: Clojure version 1.1

Preconditions are new in 1.1. The actual code also works in older Clojure versions.

<lang clojure>(defn dot-product [c1 c2]

 {:pre [(== (count c1) (count c2))]}
 (reduce + (map * c1 c2)))
Example Usage

(println (dot-product [1 3 -5] [4 -2 -1]))</lang>

Common Lisp

<lang lisp>(defun dot-product (a b)

 (apply #'+ (mapcar #'* (coerce a 'list) (coerce b 'list))))</lang>

This works with any size vector, and (as usual for Common Lisp) all numeric types (rationals, bignums, complex numbers, etc.).


Delphi

Works with: Lazarus

<lang delphi>procedure DotProduct(const A, B : doublearray; var outarray: doublearray); var i: integer;

begin

 assert (length(A) = length(B), 'Input arrays must be the same length');
 SetLength(OutArray, length(A));
 for i:= 0 to length(A) - 1 do
 begin
   OutArray[i] := A[i] * B[i];
 end;

end;</lang>

Note: code requires DoubleArray to be declared in the type section (DoubleArray = array of double). Delphi does not like arrays being declared in procedure headings, so it is necessary to declare it beforehand. To use integers, modify doublearray to be an array of integer.

Erlang

<lang erlang>dotProduct(A,B) when length(A) == length(B) -> dotProduct(A,B,0); dotProduct(_,_) -> erlang:error('Vectors must have the same length.').

dotProduct([H1|T1],[H2|T2],P) -> dotProduct(T1,T2,P+H1*H2); dotProduct([],[],P) -> P.

dotProduct([1,3,-5],[4,-2,-1]).</lang>

Output: <lang>3</lang>

Factor

The built-in word v. is used to compute the dot product. It doesn't enforce that the vectors are of the same length, so here's a wrapper.

<lang factor>USING: kernel math.vectors sequences ;

dot-product ( u v -- w )
   2dup [ length ] bi@ =
   [ v. ] [ "Vector lengths must be equal" throw ] if ;</lang>
( scratchpad ) { 1 3 -5 } { 4 -2 -1 } dot-product .
3

Forth

<lang forth>: vector create cells allot ;

th cells + ;

3 constant /vector /vector vector a /vector vector b

dotproduct ( a1 a2 -- n)
 0 tuck ?do -rot over i th @ over i th @ * >r rot r> + loop nip nip
vector! cells over + swap ?do i ! 1 cells +loop ;

-5 3 1 a /vector vector! -1 -2 4 b /vector vector!

a b /vector dotproduct . 3 ok</lang>

Fortran

Works with: Fortran version 90 and later

<lang fortran>program test_dot_product

 write (*, '(i0)') dot_product ((/1, 3, -5/), (/4, -2, -1/))

end program test_dot_product</lang> Output: <lang>3</lang>

Haskell

<lang haskell>dotp a b | length a == length b = sum (zipWith (*) a b)

        | otherwise = error "Vector sizes must match"

main = print $ dotp [1, 3, -5] [4, -2, -1] -- prints 3</lang>

J

<lang j> 1 3 _5 +/ . * 4 _2 _1 3

  dotp=: +/ . *                  NB. Or defined as a verb (function)
  1 3 _5  dotp 4 _2 _1

3</lang> The verbs built using the conjunction . generally apply to matricies and arrays of higher dimensions and can be built with verbs (functions) other than sum ( +/ ) and product ( */ ).

Java

<lang java> public class DotProduct {

public static void main(String[] args) { double[] a = {1, 3, -5}; double[] b = {4, -2, -1};

System.out.println(dotProd(a,b)); }

public static double dotProd(double[] a, double[] b){ if(a.length != b.length){ throw new IllegalArgumentException("The dimensions have to be equal!"); } double sum = 0; for(int i = 0; i < a.length; i++){ sum += a[i] * b[i]; } return sum; } }

</lang>

Output: <lang>3.0</lang>

JavaScript

<lang javascript>function dot_product(ary1, ary2) {

   if (ary1.length != ary2.length)
       throw "can't find dot product: arrays have different lengths";
   var dotprod = 0;
   for (var i = 0; i < ary1.length; i++)
       dotprod += ary1[i] * ary2[i];
   return dotprod;

}

print(dot_product([1,3,-5],[4,-2,-1])); // ==> 3 print(dot_product([1,3,-5],[4,-2,-1,0])); // ==> exception</lang>

Liberty BASIC

<lang lb>dim a(2) dim b(2)

a(0) = 1 : a(1) = 3 : a(2) = -5 b(0) = 4 : b(1) = -2 : b(2) = -1


for i = 0 to 2

   result = result + (a(i) * b(i))

next i

print result</lang>

<lang logo>to dotprod :a :b

 output apply "sum (map "product :a :b)

end

show dotprod [1 3 -5] [4 -2 -1]  ; 3</lang>

Lua

<lang lua>function dotprod(a, b)

 local ret = 0
 for i = 1, #a do
   ret = ret + a[i] * b[i]
 end
 return ret

end

print(dotprod({1, 3, -5}, {4, -2, 1}))</lang>

MATLAB

The dot product operation is a built-in function that operates on vectors of arbitrary length. <lang>A = [1 3 -5] B = [4 -2 -1] C = dot(A,B)</lang>

For the Octave implimentation: <lang>function C = DotPro(A,B)

 C = sum( A.*B );

end</lang>

MUMPS

<lang MUMPS>DOTPROD(A,B)

;Returns the dot product of two vectors. Vectors are assumed to be stored as caret-delimited strings of numbers.
;If the vectors are not of equal length, a null string is returned.
QUIT:$LENGTH(A,"^")'=$LENGTH(B,"^") ""
NEW I,SUM
SET SUM=0
FOR I=1:1:$LENGTH(A,"^") SET SUM=SUM+($PIECE(A,"^",I)*$PIECE(B,"^",I))
KILL I
QUIT SUM</lang>

Objective-C

<lang objc>#import <stdio.h>

  1. import <stdint.h>
  2. import <stdlib.h>
  3. import <string.h>
  4. import <objc/Object.h>

// this class exists to return a result between two // vectors: if vectors have different "size", valid // must be NO @interface VResult : Object {

@private
 double value;
 BOOL valid;

} +(id)new: (double)v isValid: (BOOL)y; -(id)init: (double)v isValid: (BOOL)y; -(BOOL)isValid; -(double)value; @end

@implementation VResult +(id)new: (double)v isValid: (BOOL)y {

 id s = [super new];
 [s init: v isValid: y];
 return s;

} -(id)init: (double)v isValid: (BOOL)y {

 value = v;
 valid = y;
 return self;

} -(BOOL)isValid { return valid; } -(double)value { return value; } @end


@interface RCVector : Object {

@private
 double *vec;
 uint32_t size;

} +(id)newWithArray: (double *)v ofLength: (uint32_t)l; -(id)initWithArray: (double *)v ofLength: (uint32_t)l; -(VResult *)dotProductWith: (RCVector *)v; -(uint32_t)size; -(double *)array; -(void)free; @end

@implementation RCVector +(id)newWithArray: (double *)v ofLength: (uint32_t)l {

 id s = [super new];
 [s initWithArray: v ofLength: l];
 return s;

} -(id)initWithArray: (double *)v ofLength: (uint32_t)l {

 size = l;
 vec = malloc(sizeof(double) * l);
 if ( vec != NULL ) {
   memcpy(vec, v, sizeof(double)*l);
   return self;
 }
 [super free];
 return nil;

} -(void)free {

 if ( vec != NULL ) { free(vec); }
 [super free];

} -(uint32_t)size { return size; } -(double *)array { return vec; } -(VResult *)dotProductWith: (RCVector *)v {

 double r = 0.0;
 uint32_t i, s;
 double *v1;
 if ( [self size] != [v size] ) return [VResult new: r isValid: NO];
 s = [self size];
 v1 = [v array];
 for(i = 0; i < s; i++) {
   r += vec[i] * v1[i];
 }
 return [VResult new: r isValid: YES];

} @end

double val1[] = { 1, 3, -5 }; double val2[] = { 4,-2, -1 };

int main() {

 RCVector *v1 = [RCVector newWithArray: val1 ofLength: sizeof(val1)/sizeof(double)];
 RCVector *v2 = [RCVector newWithArray: val2 ofLength: sizeof(val1)/sizeof(double)];
 VResult *r = [v1 dotProductWith: v2];
 if ( [r isValid] ) {
   printf("%lf\n", [r value]);
 } else {
   fprintf(stderr, "length of vectors differ\n");
 }
 return 0;

}</lang>

Objeck

<lang objeck> bundle Default {

 class DotProduct {
   function : Main(args : String[]) ~ Nil {
     DotProduct([1, 3, -5], [4, -2, -1])->PrintLine();
   }
   
   function : DotProduct(array_a : Int[], array_b : Int[]) ~ Int {
     if(array_a = Nil) {
       return 0;
     };
    
     if(array_b = Nil) {
       return 0;
     };
    
     if(array_a->Size() <> array_b->Size()) {
       return 0;
     };
     
     val := 0;
     for(x := 0; x < array_a->Size(); x += 1;) {
       val += (array_a[x] * array_b[x]);
     };
    
     return val;
   }
 }

} </lang>

OCaml

<lang ocaml>let dot a b =

 let n = Array.length a in
 if n <> Array.length b then failwith "arrays are not the same length";
 let rec g s = function
 | 0 -> s
 | i ->
     g (s +. a.(i-1)*.b.(i-1)) (i-1)
 in
 g 0.0 n

dot [| 1.0; 3.0; -5.0 |] [| 4.0; -2.0; -1.0 |];; (* - : float = 3. *)</lang>

Octave

See Dot product#MATLAB for an implementation. If we have a row-vector and a column-vector, we can use simply *.

<lang octave>a = [1, 3, -5] b = [4, -2, -1] % or [4; -2; -1] and avoid transposition with ' disp( a * b' )  % ' means transpose</lang>

Oz

Vectors are represented as lists in this example. <lang oz>declare

 fun {DotProduct Xs Ys}
    {Length Xs} = {Length Ys} %% assert
    {List.foldL {List.zip Xs Ys Number.'*'} Number.'+' 0}
 end

in

 {Show {DotProduct [1 3 ~5] [4 ~2 ~1]}}</lang>

Perl

<lang perl>sub dotprod {

       my($vec_a, $vec_b) = @_;
       die "they must have the same size\n" unless @$vec_a == @$vec_b;
       my $sum = 0;
       $sum += $vec_a->[$_] * $vec_b->[$_] for 0..$#$vec_a;
       return $sum;

}

my @vec_a = (1,3,-5); my @vec_b = (4,-2,-1);

print dotprod(@vec_a,@vec_b), "\n"; # 3</lang>

Perl 6

Works with: Rakudo version 2010.07

We use the square-bracket meta-operator to turn the infix operator + into a reducing list operator, and the guillemet meta-operator to vectorize the infix operator *. Length validation is automatic in this form.

<lang perl6>say [+] (1, 3, -5) »*« (4, -2, 1);</lang>

PicoLisp

<lang PicoLisp>(de dotProduct (A B)

  (sum * A B) )

(dotProduct (1 3 -5) (4 -2 -1))</lang> Output:

-> 3

PL/I

<lang PL/I> get (n); begin;

  declare (A(n), B(n)) float;
  declare dot_product float;
  get list (A);
  get list (B);
  dot_product = sum(a*b);
  put (dot_product);

end; </lang>

PostScript

<lang> /dotproduct{ /x exch def /y exch def /sum 0 def /i 0 def x length y length eq %Check if both arrays have the same length { x length{ /sum x i get y i get mul sum add def /i i 1 add def }repeat sum == } { -1 == }ifelse }def </lang>

PureBasic

<lang PureBasic>Procedure dotProduct(Array a.i(1), Array b.i(1), length.i)

 Protected result.i, i.i
 
 For i = 0 To length - 1
   result + a(i) * b(i)
 Next
 
 ProcedureReturn result

EndProcedure

Dim a.i(2) a(0) = 1 : a(1) = 3 : a(2) = -5 Dim b.i(2) b(0) = 4 : b(1) = -2 : b(2) = -1

Debug dotProduct(a(), b(), 3) </lang>

Python

<lang python>def dotp(a,b):

   assert len(a) == len(b), 'Vector sizes must match'
   return sum(aterm * bterm for aterm,bterm in zip(a, b))

if __name__ == '__main__':

   a, b = [1, 3, -5], [4, -2, -1]
   assert dotp(a,b) == 3</lang>

R

Here are several ways to do the task.

<lang R> x <- c(1, 3, -5) y <- c(4, -2, -1)

sum(x*y) # compute products, then do the sum x %*% y # inner product

  1. loop implementation

dotp <- function(x, y) { n <- length(x) if(length(y) != n) stop("invalid argument") s <- 0 for(i in 1:n) s <- s + x[i]*y[i] s }

dotp(x, y) </lang>

RLaB

In its simplest form dot product is a composition of two functions: element-by-element multiplication '.*' followed by sumation of an array. Consider an example: <lang RLaB> x = rand(1,10); y = rand(1,10); s = sum( x .* y ); </lang>

Warning: element-by-element multiplication is matrix optimized. As the interpretation of the matrix optimization is quite general, and unique to RLaB, any two matrices can be so multiplied irrespective of their dimensions. It is up to user to check whether in his/her case the matrix optimization needs to be restricted, and then to implement restrictions in his/her code.

Ruby

<lang ruby>class Array

 def dot_product(other)
   raise "not the same size!" if self.length != other.length
   self.zip(other).inject(0) {|dp, (a, b)| dp += a*b}
 end

end

p [1, 3, -5].dot_product [4, -2, -1] # => 3</lang>

Sather

Built-in class VEC "implements" euclidean (geometric) vectors. <lang sather>class MAIN is

 main is
   x ::= #VEC(|1.0, 3.0, -5.0|);
   y ::= #VEC(|4.0, -2.0, -1.0|);
   #OUT + x.dot(y) + "\n";
 end;

end;</lang>

Scala

Works with: Scala version 2.8

<lang scala>class Dot[T](v1: Seq[T])(implicit n: Numeric[T]) {

 import n._
 def dot(v2: Seq[T]) = {
   require(v1.length == v2.length)
   v1 zip v2 map Function.tupled(_*_) sum
 }

}

implicit def toDot[T : Numeric](v1: Seq[T]) = new Dot(v1) val v1 = List(1, 3, -5) val v2 = List(4, -2, -1) println(v1 dot v2)</lang>

Seed7

<lang seed7>$ include "seed7_05.s7i";

$ syntax expr: .().dot.() is -> 6; # priority of dot operator

const func integer: (in array integer: a) dot (in array integer: b) is func

 result
   var integer: sum is 0;
 local
   var integer: index is 0;
 begin
   if length(a) <> length(b) then
     raise RANGE_ERROR;
   else
     for index range 1 to length(a) do
       sum +:= a[index] * b[index];
     end for;
   end if;
 end func;

const proc: main is func

 begin
   writeln([](1, 3, -5) dot [](4, -2, -1));
 end func;</lang>

Scheme

Works with: Scheme version RRS

<lang scheme>(define (dot-product a b)

 (apply + (map * a b)))

(display (dot-product (list 1 3 -5) (list 4 -2 -1))) (newline)</lang> Output: <lang>3</lang>

Smalltalk

Works with: GNU Smalltalk

<lang smalltalk>Array extend [

 * anotherArray [
      |acc| acc := 0.
      self with: anotherArray collect: [ :a :b |
         acc := acc + ( a * b )
      ].
      ^acc
 ]

]

( #(1 3 -5) * #(4 -2 -1 ) ) printNl.</lang>

SNOBOL4

<lang snobol4> define("dotp(a,b)sum,i")  :(dotp_end) dotp i = 1; sum = 0 loop sum = sum + (a * b)

       i = i + 1 ?a :s(loop)
       dotp = sum      :(return)

dotp_end

       a = array(3); a<1> = 1; a<2> = 3; a<3> = -5; 
       b = array(3); b<1> = 4; b<2> = -2; b<3> = -1;
       output = dotp(a,b)

end</lang>

Tcl

Library: tcllib

<lang tcl>package require math::linearalgebra

set a {1 3 -5} set b {4 -2 -1} set dotp [::math::linearalgebra::dotproduct $a $b] proc pp vec {return \[[join $vec ,]\]} puts "[pp $a] \u2219 [pp $b] = $dotp"</lang> Output:

[1,3,-5] ∙ [4,-2,-1] = 3.0

TI-89 BASIC

dotP([1, 3, –5], [4, –2, –1])
    3

Ursala

A standard library function for dot products of floating point numbers exists, but a new one can be defined for integers as shown using the map operator (*) with the zip suffix (p) to construct a "zipwith" operator (*p), which operates on the integer product function. A catchable exception is thrown if the list lengths are unequal. This function is then composed (+) with a cumulative summation function, which is constructed from the binary sum function, and the reduction operator (:-) with 0 specified for the vacuous sum. <lang Ursala>#import int

dot = sum:-0+ product*p

  1. cast %z

test = dot(<1,3,-5>,<4,-2,-1>)</lang> output:

3