vec.sa


Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
 
---------------------------> Sather 1.1 source file <--------------------------
-- Copyright (C) International Computer Science Institute, 1994.  COPYRIGHT  --
-- NOTICE: This code is provided "AS IS" WITHOUT ANY WARRANTY and is subject --
-- to the terms of the SATHER LIBRARY GENERAL PUBLIC LICENSE contained in    --
-- the file "Doc/License" of the Sather distribution.  The license is also   --
-- available from ICSI, 1947 Center St., Suite 600, Berkeley CA 94704, USA.  --
--------> Please email comments to sather-bugs@icsi.berkeley.edu. <----------
-- Author: Matthew B. Kennel <mbk@caffeine.engr.utk.edu>


partial class VEC{ET<$REAL_NUMBER{ET}}

partial class VEC{ET<$REAL_NUMBER{ET}} is -- Partial becauseit requires VECTOR_LENGTH_MIXIN's to complete itself -- We cannot subtype this generic from $VEC{ET,SAME}, though -- instantiations of this type should be subtyped from the proper -- abstract. c.f. 'mat.sa'. -- -- This is a pure Sather implementation of the basic vector class. -- "length" and dot product operations will NOT be implemented here, -- but in auxiliary 'partial' (non-instantiable) classes that are -- designed for only implementation inheritance. -- A concrete vector class of floating point numbers then would inherit -- from this class, and the auxiliary 'length' implementation suitable for -- it, and then subtype from the proper generics. -- Finally, for some element types, such as floating point numbers, there -- will be implementations that may over-ride some of the implementaitons -- in this class and replace them with BLAS calls. -- -- What is the difference between a VEC and an ARRAY? -- An ARRAY is more a full-featured container class; a VEC is intended -- as the target space of a linear operator, which might be its associated -- matrix for instance. Therefore ARRAY has features for sorting -- and many copying iters, which may not all make sense in a VEC context. -- For instance anything which changes the size of an ARRAY is not -- appropriate for VEC. include AREF{ET}; element_zero:ET is return ET::zero; end; element_one:ET is return ET::one; end; dim:INT is return asize end; same_size(arg:SAME):BOOL is if void(arg) or void(self) then return false; elsif arg.asize /= asize then return false; else return true; end; end; is_eq(arg:SAME):BOOL pre same_size(arg) is loop if aelt! /= arg.aelt! then return false; end; end; return true; end; create(sz:INT):SAME is res ::= new(sz); return res; end; create(arg:SAME):SAME pre ~void(arg) is res ::= new(arg.asize); return res; end; create(arg:ARRAY{ET}):SAME pre ~void(arg) is res ::= new(arg.asize); loop res.aset!(arg.elt!); end; return(res); end; str:STR is -- Return a string representing the vector -- Eg. |0,1| res ::= #FSTR+"|"; loop res := res + aelt!(0,dim-1).str + ","; end; res := res + [dim-1].str + "|"; return(res.str); end; array:ARRAY{ET} pre ~void(self) is res ::= #ARRAY{ET}(dim); loop res.set!(aelt!) end; end; copy:SAME pre ~void(self) is res ::= create(asize); res.acopy(self); -- should be built in fast routine return res; end; inplace_contents(arg:SAME) pre same_size(arg) is self.acopy(arg); end; inplace_contents_subspace(destbeg,n,srcbeg:INT,arg:SAME) pre ~void(self) and ~void(arg) and n >= 0 and destbeg.is_bet(0,asize-1) and n.is_bet(0,asize-destbeg) and n <= arg.asize - srcbeg (* whew *) is acopy(destbeg,n,srcbeg,arg); -- should be built-in fast routine. end; inplace_contents_from_function(function:ROUT{INT}:ET) pre ~void(self) is loop idx ::= asize.times!; [idx] := function.call(idx); end; end; inplace_elements(arg:ET) pre ~void(self) is loop aset!(arg); end; end; inplace_unit_vector(i:INT) pre ~void(self) and i.is_bet(0,asize-1) is loop idx ::= asize.times!; if idx = i then [i] := element_one; else [i] := element_zero; end; end; end; times(s:ET):SAME pre ~void(self) is res ::= new(asize); loop i ::= asize.times!; res[i] := [i]*s; end; return res; end; scaled_by(s:ET):SAME is return times(s); end; inplace_scaled_by(s:ET) pre ~void(self) is loop i ::= asize.times!; [i] := [i]*s; end; end; plus(arg:SAME):SAME is res ::= new(asize); res.inplace_arg_plus_arg(self,arg); return res; end; plus_arg(arg:SAME):SAME is return plus(arg); end; minus(arg:SAME):SAME is res ::= new(asize); res.inplace_arg_minus_arg(self,arg); return res end; minus_arg(arg:SAME):SAME is return minus(arg); end; inplace_plus_arg(arg:SAME) pre same_size(arg) is loop i ::= asize.times!; [i] := [i] + arg[i]; end; end; inplace_minus_arg(arg:SAME) pre same_size(arg) is loop i ::= asize.times!; [i] := [i] - arg[i]; end; end; inplace_arg_plus_arg(arg1,arg2:SAME) pre same_size(arg1) and arg1.same_size(arg2) is loop i ::= asize.times!; [i] := arg1[i] + arg2[i]; end; end; inplace_arg_minus_arg(arg1,arg2:SAME) pre same_size(arg1) and arg1.same_size(arg2) is loop i ::= asize.times!; [i] := arg1[i] - arg2[i]; end; end; plus_scaled_arg(s:ET,arg:SAME):SAME pre same_size(arg) is res ::= new(asize); res.inplace_arg_plus_scaled_arg(self,s,arg); return res; end; inplace_plus_scaled_arg(s:ET,arg:SAME) pre same_size(arg) is loop i ::= asize.times!; [i] := [i] + s*arg[i]; end; end; inplace_arg_plus_scaled_arg(arg1:SAME,s:ET,arg2:SAME) pre same_size(arg1) and arg1.same_size(arg2) is loop i ::= asize.times!; [i] := arg1[i] + s*arg2[i]; end; end; inplace_swapped(arg:SAME) pre same_size(arg) is loop i ::= asize.times!; tmp ::= [i]; [i] := arg[i]; arg[i] := tmp; end; end; end;

partial class VEC_LENGTH_MIXIN{ET<$REAL_NUMBER{ET},VT<$VEC{ET,VEC}}

partial class VEC_LENGTH_MIXIN{ET<$REAL_NUMBER{ET},VT<$VEC{ET,VEC}} is -- -- NOTE most of the these definitions are NOT good for complex numbers. -- include VEC{ET}; length_zero:ET is return ET::zero; end; length_one:ET is return ET::one; end; dot(arg:SAME):ET pre same_size(arg) is res::= element_zero; loop i ::= asize.times!; res := res + [i]*arg[i]; end; return res; end; angle_with(arg:SAME):ET is return cosine_angle_with(arg).acos; end; cosine_angle_with(arg:SAME):ET pre same_size(arg) is -- cos theta = a dot b / |a|*|b| return dot(arg) / (length * arg.length); end; length_squared:ET is return dot(self); end; length:ET is return length_squared.sqrt; end; distance_to_squared(arg:SAME):ET pre same_size(arg) is -- we could implement in terms of other functions but I will -- hand-write for speed. res ::= length_zero; loop i ::= asize.times!; t ::= [i]-arg[i]; res := res + t*t; end; return res; end; distance_to(arg:SAME):ET is return distance_to_squared(arg).sqrt; end; bounded_distance_to_squared(arg:SAME,sbnd:ET):ET pre same_size(arg) is -- we could implement in terms of other functions but I will -- hand-write for speed. res ::= length_zero; loop i ::= asize.times!; t ::= [i]-arg[i]; res := res + t*t; if res > sbnd then return length_one.negate; end; end; return res; end; inplace_normalized is inplace_scaled_by(length_one / length); end; end;

class VEC < $VEC{FLT,VEC,FLT}

class VEC < $VEC{FLT,VEC,FLT} is -- Concrete instantiation of a standard vector include VEC_LENGTH_MIXIN{FLT,SAME}; const element_zero:FLT := 0.0; const element_one:FLT := 1.0; const length_zero:FLT := 0.0; const length_one:FLT := 1.0; max_value: FLT is max: FLT := FLT::minval; loop i ::= asize.times!; if [i] > max then max := [i]; end; end; return max; end; end;