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.
- Reference
- Vector products here on RC.
ABAP
<lang ABAP>report zdot_product data: lv_n type i,
lv_sum type i, lt_a type standard table of i, lt_b type standard table of i.
append: '1' to lt_a, '3' to lt_a, '-5' to lt_a. append: '4' to lt_b, '-2' to lt_b, '-1' to lt_b. describe table lt_a lines lv_n.
perform dot_product using lt_a lt_b lv_n changing lv_sum.
write lv_sum left-justified.
form dot_product using it_a like lt_a
it_b like lt_b iv_n type i changing ev_sum type i. field-symbols: <wa_a> type i, <wa_b> type i.
do iv_n times. read table: it_a assigning <wa_a> index sy-index, it_b assigning <wa_b> index sy-index. lv_sum = lv_sum + ( <wa_a> * <wa_b> ). enddo.
endform.</lang> Output:
3
ACL2
<lang Lisp>(defun dotp (v u)
(if (or (endp v) (endp u)) 0 (+ (* (first v) (first u)) (dotp (rest v) (rest u)))))</lang>
> (dotp '(1 3 -5) '(4 -2 -1)) 3
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
<lang algol68>MODE DOTFIELD = REAL; MODE DOTVEC = [1:0]DOTFIELD;
- 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
);
- 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
- 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
);
- 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>
AWK
<lang AWK>
- syntax: GAWK -f DOT_PRODUCT.AWK
BEGIN {
v1 = "1,3,-5" v2 = "4,-2,-1" if (split(v1,v1arr,",") != split(v2,v2arr,",")) { print("error: vectors are of unequal lengths") exit(1) } printf("%g\n",dot_product(v1arr,v2arr)) exit(0)
} function dot_product(v1,v2, i,sum) {
for (i in v1) { sum += v1[i] * v2[i] } return(sum)
} </lang>
output:
3
BBC BASIC
BBC BASIC has a built-in dot-product operator: <lang bbcbasic> DIM vec1(2), vec2(2), dot(0)
vec1() = 1, 3, -5 vec2() = 4, -2, -1 dot() = vec1() . vec2() PRINT "Result is "; dot(0)</lang>
Output:
Result is 3
Befunge 93
<lang befunge> v Space for variables v Space for vector1 v Space for vector2 v http://rosettacode.org/wiki/Dot_product
>00pv
>>55+":htgneL",,,,,,,,&:0` | v,,,,,,,"Length can't be negative."+55< >,,,,,,,,,,,,,,,,,,,@ |!`-10<
>0.@
v,")".g00,,,,,,,,,,,,,,"Vector a(size " < 0v01g00,")".g00,,,,,,,,,,,,,,"Vector b"< 0pvp2g01&p01-1g01< " g>> 10g0`| @.g30<( 1 >03g:-03p>00g1-` |s 0 vp00-1g00p30+g30*g2-1g00g1-1g00 v # z vp1g01&p01-1g01<> ^ e > 10g0` | vp01-1g01.g1<
>00g1-10p>10g:01-` | " > ^
</lang> Output: Length: 3 Vector a(size 3 )1 3 -5 1 3 -5 Vector b(size 3 )4 -2 -1 3
Bracmat
<lang bracmat> ( dot
= a A z Z . !arg:(%?a ?z.%?A ?Z) & !a*!A+dot$(!z.!Z) | 0 )
& out$(dot$(1 3 -5.4 -2 -1));</lang> Output:
3
C
<lang c>#include <stdio.h>
- 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:
3
C#
<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:
3
Alternative using Linq (C# 4)
<lang csharp>public static decimal DotProduct(decimal[] a, decimal[] b) {
return a.Zip(b, (x, y) => x * y).Sum();
}</lang>
C++
<lang cpp>#include <iostream>
- 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:
3
Clojure
Preconditions are new in 1.1. The actual code also works in older Clojure versions. <lang clojure>(defn dot-product [& matrix]
{:pre [(apply == (map count matrix))]} (apply + (apply map * matrix)))
- Example Usage
(println (dot-product [1 3 -5] [4 -2 -1]))</lang>
CoffeeScript
<lang coffeescript>dot_product = (ary1, ary2) ->
if ary1.length != ary2.length throw "can't find dot product: arrays have different lengths" dotprod = 0 for v, i in ary1 dotprod += v * ary2[i] dotprod
console.log dot_product([ 1, 3, -5 ], [ 4, -2, -1 ]) # 3 try
console.log dot_product([ 1, 3, -5 ], [ 4, -2, -1, 0 ]) # exception
catch e
console.log e</lang>
output
> coffee foo.coffee 3 can't find dot product: arrays have different lengths
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.).
Maybe it is better to do it without coercing. Then we got a cleaner code. <lang lisp>(defun dot-prod (a b)
(reduce #'+ (map 'simple-vector #'* a b)))</lang>
D
<lang d>void main() {
import std.stdio, std.numeric;
[1.0, 3.0, -5.0].dotProduct([4.0, -2.0, -1.0]).writeln;
}</lang> Output:
3
Using an array operation: <lang d>void main() {
import std.stdio, std.range, std.algorithm;
double[3] a = [1.0, 3.0, -5.0]; double[3] b = [4.0, -2.0, -1.0]; double[3] c; c[] = a[] * b[]; c.reduce!q{a + b}.writeln;
}</lang>
Delphi
<lang delphi>program Project1;
{$APPTYPE CONSOLE}
type
doublearray = array of Double;
function DotProduct(const A, B : doublearray): Double; var I: integer; begin
assert (Length(A) = Length(B), 'Input arrays must be the same length'); Result := 0; for I := 0 to Length(A) - 1 do Result := Result + (A[I] * B[I]);
end;
var
x,y: doublearray;
begin
SetLength(x, 3); SetLength(y, 3); x[0] := 1; x[1] := 3; x[2] := -5; y[0] := 4; y[1] :=-2; y[2] := -1; WriteLn(DotProduct(x,y)); ReadLn;
end.</lang> Output:
3.00000000000000E+0000
Note: 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.
DWScript
For arbitrary length vectors, using a precondition to check vector length: <lang delphi>function DotProduct(a, b : array of Float) : Float; require
a.Length = b.Length;
var
i : Integer;
begin
Result := 0; for i := 0 to a.High do Result += a[i]*b[i];
end;
PrintLn(DotProduct([1,3,-5], [4,-2,-1]));</lang> Using built-in 4D Vector type: <lang delphi>var a := Vector(1, 3, -5, 0); var b := Vector(4, -2, -1, 0);
PrintLn(a * b);</lang>
Ouput in both cases:
3
Ela
Translation of Haskell:
<lang ela>open list
dotp a b | length a == length b = sum (zipWith (*) a b)
| else = fail "Vector sizes must match."
dotp [1,3,-5] [4,-2,-1]</lang>
Output:
3
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:
3
Euphoria
<lang Euphoria>function dotprod(sequence a, sequence b)
atom sum a *= b sum = 0 for n = 1 to length(a) do sum += a[n] end for return sum
end function
? dotprod({1,3,-5},{4,-2,-1})</lang>
Sample Output: 3
<lang Euphoria>-- Here is an alternative method, -- using the standard Euphoria Version 4+ Math Library include std/math.e sequence a = {1,3,-5}, b = {4,-2,-1} -- Make them any length you want ? sum(a * b)</lang>
Sample Output: 3
F#
<lang fsharp>let dot_product (a:array<'a>) (b:array<'a>) =
if Array.length a <> Array.length b then failwith "invalid argument: vectors must have the same lengths" Array.fold2 (fun acc i j -> acc + (i * j)) 0 a b</lang>
> dot_product [| 1; 3; -5 |] [| 4; -2; -1 |] ;; val it : int = 3
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
FALSE
<lang false>[[\1-$0=~][$d;2*1+\-ø\$d;2+\-ø@*@+]#]p: 3d: {Vectors' length} 1 3 5_ 4 2_ 1_ d;$1+ø@*p;!%. {Output: 3}</lang>
Fantom
Dot product of lists of Int: <lang fantom>class DotProduct {
static Int dotProduct (Int[] a, Int[] b) { Int result := 0 [a.size,b.size].min.times |i| { result += a[i] * b[i] } return result }
public static Void main () { Int[] x := [1,2,3,4] Int[] y := [2,3,4]
echo ("Dot product of $x and $y is ${dotProduct(x, y)}") }
}</lang>
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
<lang fortran>program test_dot_product
write (*, '(i0)') dot_product ((/1, 3, -5/), (/4, -2, -1/))
end program test_dot_product</lang> Output:
3
GAP
<lang gap># Built-in
[1, 3, -5]*[4, -2, -1];
- 3</lang>
Go
<lang go>package main
import (
"errors" "fmt"
)
func dot(x, y []int) (r int, err error) {
if len(x) != len(y) { return 0, errors.New("incompatible lengths") } for i := range x { r += x[i] * y[i] } return
}
func main() {
d, err := dot([]int{1, 3, -5}, []int{4, -2, -1}) if err != nil { fmt.Println(err) return } fmt.Println(d)
}</lang> Output:
3
Groovy
Solution: <lang groovy>def dotProduct = { x, y ->
assert x && y && x.size() == y.size() [x, y].transpose().collect{ it[0] * it[1] }.sum()
}</lang> Test: <lang groovy>println dotProduct([1, 3, -5], [4, -2, -1])</lang> Output:
3
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>
Icon and Unicon
The procedure below computes the dot product of two vectors of arbitrary length or generates a run time error if its arguments are the wrong type or shape. <lang Icon>procedure main() write("a dot b := ",dotproduct([1, 3, -5],[4, -2, -1])) end
procedure dotproduct(a,b) #: return dot product of vectors a & b or error if *a ~= *b & type(a) == type(b) == "list" then runerr(205,a) # invalid value every (dp := 0) +:= a[i := 1 to *a] * b[i] return dp end</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>
Note also: 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:
3.0
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>
Julia
Linear algebra functions in Julia are largely implemented by calling functions from LAPACK. <lang julia> x = [1, 3, -5] y = [4, -2, -1] z = dot(x, y) </lang>
K
<lang K> +/1 3 -5 * 4 -2 -1 3
1 3 -5 _dot 4 -2 -1
3</lang>
LFE
<lang lisp>(defun dot-product (a b)
(: lists foldl #'+/2 0 (: lists zipwith #'*/2 a b)))
</lang>
Liberty BASIC
<lang lb>vectorA$ = "1, 3, -5" vectorB$ = "4, -2, -1" print "DotProduct of ";vectorA$;" and "; vectorB$;" is "; print DotProduct(vectorA$, vectorB$)
'arbitrary length vectorA$ = "3, 14, 15, 9, 26" vectorB$ = "2, 71, 18, 28, 1" print "DotProduct of ";vectorA$;" and "; vectorB$;" is "; print DotProduct(vectorA$, vectorB$)
end
function DotProduct(a$, b$)
DotProduct = 0 i = 1 while 1 x$=word$( a$, i, ",") y$=word$( b$, i, ",") if x$="" or y$="" then exit function DotProduct = DotProduct + val(x$)*val(y$) i = i+1 wend
end function </lang>
Logo
<lang logo>to dotprod :a :b
output apply "sum (map "product :a :b)
end
show dotprod [1 3 -5] [4 -2 -1] ; 3</lang>
Logtalk
<lang logtalk>dot_product(A, B, Sum) :-
dot_product(A, B, 0, Sum).
dot_product([], [], Sum, Sum). dot_product([A| As], [B| Bs], Acc, Sum) :-
Acc2 is Acc + A*B, dot_product(As, Bs, Acc2, Sum).</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>
Mathematica
<lang Mathematica>{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 matlab>A = [1 3 -5] B = [4 -2 -1] C = dot(A,B)</lang> For the Octave implimentation: <lang matlab>function C = DotPro(A,B)
C = sum( A.*B );
end</lang>
Maxima
<lang maxima>[1, 3, -5] . [4, -2, -1]; /* 3 */</lang>
Mercury
This will cause a software_error/1 exception if the lists are of different lengths. <lang mercury>:- module dot_product.
- - interface.
- - import_module io.
- - pred main(io::di, io::uo) is det.
- - implementation.
- - import_module int, list.
main(!IO) :-
io.write_int([1, 3, -5] `dot_product` [4, -2, -1], !IO), io.nl(!IO).
- - func dot_product(list(int), list(int)) = int.
dot_product(As, Bs) =
list.foldl_corresponding((func(A, B, Acc) = Acc + A * B), As, Bs, 0).</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>
Nemerle
This will cause an exception if the arrays are different lengths. <lang Nemerle>using System; using System.Console; using Nemerle.Collections.NCollectionsExtensions;
module DotProduct {
DotProduct(x : array[int], y : array[int]) : int { $[(a * b)|(a, b) in ZipLazy(x, y)].FoldLeft(0, _+_); } Main() : void { def arr1 = array[1, 3, -5]; def arr2 = array[4, -2, -1]; WriteLine(DotProduct(arr1, arr2)); }
}</lang>
NetRexx
<lang NetRexx>/* NetRexx */ options replace format comments java crossref savelog symbols binary
whatsTheVectorVictor = [[double 1.0, 3.0, -5.0], [double 4.0, -2.0, -1.0]] dotProduct = Rexx dotProduct(whatsTheVectorVictor) say dotProduct.format(null, 2)
return
method dotProduct(vec1 = double[], vec2 = double[]) public constant returns double signals IllegalArgumentException
if vec1.length \= vec2.length then signal IllegalArgumentException('Vectors must be the same length')
scalarProduct = double 0.0 loop e_ = 0 to vec1.length - 1 scalarProduct = vec1[e_] * vec2[e_] + scalarProduct end e_
return scalarProduct
method dotProduct(vecs = double[,]) public constant returns double signals IllegalArgumentException
return dotProduct(vecs[0], vecs[1])</lang>
newLISP
<lang newLISP>(define (dot-product x y)
(apply + (map * x y)))
(println (dot-product '(1 3 -5) '(4 -2 -1)))</lang>
Objective-C
<lang objc>#import <stdio.h>
- import <stdint.h>
- import <stdlib.h>
- import <string.h>
- 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 {
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
With lists: <lang ocaml>let dot = List.fold_left2 (fun z x y -> z +. x *. y) 0.
(*
- dot [1.0; 3.0; -5.0] [4.0; -2.0; -1.0];;
- : float = 3.
- )</lang>
With arrays: <lang ocaml>let dot v u =
if Array.length v <> Array.length u then invalid_arg "Different array lengths"; let times v u = Array.mapi (fun i v_i -> v_i *. u.(i)) v in Array.fold_left (+.) 0. (times v u)
(*
- 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>
PARI/GP
<lang parigp>dot(u,v)={
sum(i=1,#u,u[i]*v[i])
};</lang>
Pascal
See Delphi
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
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>
PHP
<lang php><?php function dot_product($v1, $v2) {
if (count($v1) != count($v2)) throw new Exception('Arrays have different lengths'); return array_sum(array_map('bcmul', $v1, $v2));
}
echo dot_product(array(1, 3, -5), array(4, -2, -1)), "\n"; ?></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 postscript>/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>
Prolog
Works with SWI-Prolog. <lang Prolog>dot_product(L1, L2, N) :- maplist(mult, L1, L2, P), sumlist(P, N).
mult(A,B,C) :- C is A*B.</lang> Example :
?- dot_product([1,3,-5], [4,-2,-1], N). N = 3.
PureBasic
<lang PureBasic>Procedure dotProduct(Array a(1),Array b(1))
Protected i, sum, length = ArraySize(a())
If ArraySize(a()) = ArraySize(b()) For i = 0 To length sum + a(i) * b(i) Next EndIf
ProcedureReturn sum
EndProcedure
If OpenConsole()
Dim a(2) Dim b(2) a(0) = 1 : a(1) = 3 : a(2) = -5 b(0) = 4 : b(1) = -2 : b(2) = -1 PrintN(Str(dotProduct(a(),b()))) Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input() CloseConsole()
EndIf</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
- 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>
Racket
<lang Racket>
- lang racket
(define (dot-product l r) (for/sum ([x l] [y r]) (* x y)))
(dot-product '(1 3 -5) '(4 -2 -1))
- dot-product works on sequences such as vectors
(dot-product #(1 2 3) #(4 5 6)) </lang>
Rascal
<lang Rascal>import List;
public int dotProduct(list[int] L, list[int] M){ result = 0; if(size(L) == size(M)) { while(size(L) >= 1) { result += (head(L) * head(M)); L = tail(L); M = tail(M); } return result; } else { throw "vector sizes must match"; } }</lang>
Alternative solution
If a matrix is represented by a relation of <x-coordinate, y-coordinate, value>, then function below can be used to find the Dot product. <lang Rascal>import Prelude;
public real matrixDotproduct(rel[real x, real y, real v] column1, rel[real x, real y, real v] column2){ return (0.0 | it + v1*v2 | <x1,y1,v1> <- column1, <x2,y2,v2> <- column2, y1==y2); }
//a matrix, given by a relation of x-coordinate, y-coordinate, value. public rel[real x, real y, real v] matrixA = { <0.0,0.0,12.0>, <0.0,1.0, 6.0>, <0.0,2.0,-4.0>, <1.0,0.0,-51.0>, <1.0,1.0,167.0>, <1.0,2.0,24.0>, <2.0,0.0,4.0>, <2.0,1.0,-68.0>, <2.0,2.0,-41.0> };</lang>
REXX
Checks could've been added to the REXX code to insure that the vector elements are numeric. <lang rexx>/*REXX program computes the dot product of two equal size vectors. */ vectorA = ' 1 3 -5 ' /*populate vectorA with numbers, */ vectorB = ' 4 -2 -1 ' /* ∙∙∙ and the same for vectorB. */ say /*display a blank line. */ say 'vector A='vectorA /*echo the vectorA's values. */ say 'vector B='vectorB /*echo the vectorB's values. */ say /*display another blank line. */ p = dotProd(vectorA, vectorB) /*go and compute the dot product.*/ say 'dot product = ' p /*show and tell the dot product. */ say /*display another a blank line. */ exit /*stick a fork in it, we're done.*/ /*──────────────────────────────────DOTPROD subroutine──────────────────*/ dotProd: procedure; parse arg A,B /*compute the dot product. */ sum = 0 /*initilize the sum to 0 (zero). */ lenA = words(A) /*length of vector A in words. */ lenB = words(B) /*length of vector B in words. */
if lenA\==lenB then do
say say '*** error! ***' say "vectors aren't the same size:" say 'vectorA length='lenA say 'vectorB length='lenB say exit 13 /*exit with return code 13. */ end
do j=1 for lenA /*multiply each number in vectors*/ sum = sum + word(A,j) * word(B,j) /*∙∙∙ and add the product to SUM.*/ end /*j*/
return sum /*return the SUM to the invoker. */</lang> output
vector A= 1 3 -5 vector B= 4 -2 -1 dot product = 3
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
With the standard library, require 'matrix' and call Vector#inner_product. <lang ruby>irb(main):001:0> require 'matrix' => true irb(main):002:0> Vector[1, 3, -5].inner_product Vector[4, -2, -1] => 3</lang> Or implement dot product. <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>
Run BASIC
<lang runbasic>v1$ = "1, 3, -5" v2$ = "4, -2, -1"
print "DotProduct of ";v1$;" and "; v2$;" is ";dotProduct(v1$,v2$) end
function dotProduct(a$, b$)
while word$(a$,i + 1,",") <> "" i = i + 1 v1$=word$(a$,i,",") v2$=word$(b$,i,",") dotProduct = dotProduct + val(v1$) * val(v2$) wend
end function</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
<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
<lang scheme>(define (dot-product a b)
(apply + (map * a b)))
(display (dot-product '(1 3 -5) '(4 -2 -1))) (newline)</lang> Output:
3
Slate
<lang slate>v@(Vector traits) <dot> w@(Vector traits) "Dot-product." [
(0 below: (v size min: w size)) inject: 0 into: [| :sum :index | sum + ((v at: index) * (w at: index))]
].</lang>
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>
SPARK
Works with SPARK GPL 2010 and GPS GPL 2010.
By defining numeric subtypes with suitable ranges we can prove statically that there will be no run-time errors. (The Simplifier leaves 2 VCs unproven, but these are clearly provable by inspection.)
The precondition enforces equality of the ranges of the two vectors. <lang ada>with Spark_IO; --# inherit Spark_IO; --# main_program; procedure Dot_Product_Main --# global in out Spark_IO.Outputs; --# derives Spark_IO.Outputs from *; is
Limit : constant := 1000; type V_Elem is range -Limit .. Limit; V_Size : constant := 100; type V_Index is range 1 .. V_Size; type Vector is array(V_Index range <>) of V_Elem;
type V_Prod is range -(Limit**2)*V_Size .. (Limit**2)*V_Size; --# assert V_Prod'Base is Integer;
subtype Index3 is V_Index range 1 .. 3; subtype Vector3 is Vector(Index3); Vect1 : constant Vector3 := Vector3'(1, 3, -5); Vect2 : constant Vector3 := Vector3'(4, -2, -1);
function Dot_Product(V1, V2 : Vector) return V_Prod --# pre V1'First = V2'First --# and V1'Last = V2'Last; is Sum : V_Prod := 0; begin for I in V_Index range V1'Range --# assert Sum in -(Limit**2)*V_Prod(I-1) .. (Limit**2)*V_Prod(I-1); loop Sum := Sum + V_Prod(V1(I)) * V_Prod(V2(I)); end loop; return Sum; end Dot_Product;
begin
Spark_IO.Put_Integer(File => Spark_IO.Standard_Output, Item => Integer(Dot_Product(Vect1, Vect2)), Width => 6, Base => 10);
end Dot_Product_Main;</lang> The output:
3
SQL
ANSI sql does not support functions and is missing some other concepts that would be needed for a general case implementation of inner product (column names and tables would need to be first class in SQL -- capable of being passed to functions).
However, inner product is fairly simple to specify in SQL.
Given two tables A
and B
where A has key columns i
and j
and B has key columns j
and k
and both have value columns N
, the inner product of A and B would be:
<lang sql>select i, k, sum(A.N*B.N) as N
from A inner join B on A.j=B.j group by i, k</lang>
Standard ML
With lists: <lang sml>val dot = ListPair.foldlEq Real.*+ 0.0
(* - dot ([1.0, 3.0, ~5.0], [4.0, ~2.0, ~1.0]); val it = 3.0 : real
- )</lang>
With vectors: <lang sml>fun dot (v, u) = (
if Vector.length v <> Vector.length u then raise ListPair.UnequalLengths else (); Vector.foldli (fn (i, v_i, z) => v_i * Vector.sub (u, i) + z) 0.0 v )
(* - dot (#[1.0, 3.0, ~5.0], #[4.0, ~2.0, ~1.0]); val it = 3.0 : real
- )</lang>
Tcl
<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
- cast %z
test = dot(<1,3,-5>,<4,-2,-1>)</lang> output:
3
XPL0
<lang XPL0>include c:\cxpl\codes;
func DotProd(U, V, L); int U, V, L; int S, I; [S:= 0; for I:= 0 to L-1 do S:= S + U(I)*V(I); return S; ];
[IntOut(0, DotProd([1, 3, -5], [4, -2, -1], 3)); CrLf(0); ]</lang>
Output:
3
- Programming Tasks
- Solutions by Programming Task
- ABAP
- ACL2
- ActionScript
- Ada
- ALGOL 68
- AutoHotkey
- AWK
- BBC BASIC
- Befunge 93
- Bracmat
- C
- C sharp
- C++
- Clojure
- CoffeeScript
- Common Lisp
- D
- Delphi
- DWScript
- Ela
- Erlang
- Euphoria
- F Sharp
- Factor
- FALSE
- Fantom
- Forth
- Fortran
- GAP
- Go
- Groovy
- Haskell
- Icon
- Unicon
- J
- Java
- JavaScript
- Julia
- K
- LFE
- Liberty BASIC
- Logo
- Logtalk
- Lua
- Mathematica
- MATLAB
- Maxima
- Mercury
- MUMPS
- Nemerle
- NetRexx
- NewLISP
- Objective-C
- Objeck
- OCaml
- Octave
- Oz
- PARI/GP
- Pascal
- Perl
- Perl 6
- PHP
- PicoLisp
- PL/I
- PostScript
- Prolog
- PureBasic
- Python
- R
- Racket
- Rascal
- REXX
- RLaB
- Ruby
- Run BASIC
- Sather
- Scala
- Seed7
- Scheme
- Slate
- Smalltalk
- SNOBOL4
- SPARK
- SQL
- Standard ML
- Tcl
- Tcllib
- TI-89 BASIC
- Ursala
- XPL0