11from __future__ import annotations
22import struct
3- from typing import cast
43
54try :
65 import numpy as np
1211class HalfVector :
1312 def __init__ (self , value : list [float ] | np .ndarray [tuple [int ], np .dtype [np .floating ]]) -> None :
1413 if isinstance (value , list ):
15- dim = len (value )
1614 try :
17- self ._value = struct . pack ( f'>HH { dim } e' , dim , 0 , * value )
18- except struct . error :
15+ self ._value = [ float ( v ) for v in value ]
16+ except ( TypeError , ValueError ) :
1917 raise ValueError ('expected list[float]' )
2018 elif NUMPY_AVAILABLE and isinstance (value , np .ndarray ):
2119 if value .ndim != 1 :
2220 raise ValueError ('expected ndim to be 1' )
2321
24- # asarray still copies if same dtype
25- if value .dtype != '>f2' :
26- value = np .asarray (value , dtype = '>f2' )
27-
28- self ._value = struct .pack ('>HH' , value .shape [0 ], 0 ) + value .tobytes ()
22+ self ._value = [float (v ) for v in value ]
2923 else :
3024 raise ValueError ('expected list or ndarray' )
3125
3226 def __repr__ (self ) -> str :
33- return f'HalfVector({ self .to_list () } )'
27+ return f'HalfVector({ self ._value } )'
3428
3529 def __eq__ (self , other : object ) -> bool :
3630 if isinstance (other , self .__class__ ):
37- return self .to_binary () == other .to_binary ()
31+ return self ._value == other ._value
3832 return False
3933
4034 def dimensions (self ) -> int :
41- dim , = cast (tuple [int ], struct .unpack_from ('>H' , self ._value ))
42- return dim
35+ return len (self ._value )
4336
4437 def to_list (self ) -> list [float ]:
45- return list ( struct . unpack_from ( f'> { self .dimensions () } e' , self . _value [ 4 :]))
38+ return self ._value
4639
4740 def to_numpy (self ) -> np .ndarray [tuple [int ], np .dtype [np .float16 ]]:
48- return np .frombuffer (self ._value , dtype = '>f2' , count = self . dimensions (), offset = 4 )
41+ return np .array (self ._value , dtype = np . float16 )
4942
5043 def to_text (self ) -> str :
51- return f'[{ "," .join ([str (v ) for v in self .to_list () ])} ]'
44+ return f'[{ "," .join ([str (v ) for v in self ._value ])} ]'
5245
5346 def to_binary (self ) -> bytes :
54- return self ._value
47+ dim = len (self ._value )
48+ return struct .pack (f'>HH{ dim } e' , dim , 0 , * self ._value )
5549
5650 @classmethod
5751 def from_text (cls , value : str ) -> HalfVector :
58- return cls ([float (v ) for v in value [1 :- 1 ].split (',' )])
52+ vec = cls .__new__ (cls )
53+ vec ._value = [float (v ) for v in value [1 :- 1 ].split (',' )]
54+ return vec
5955
6056 @classmethod
6157 def from_binary (cls , value : bytes ) -> HalfVector :
@@ -68,7 +64,7 @@ def from_binary(cls, value: bytes) -> HalfVector:
6864 raise ValueError ('expected unused to be 0' )
6965
7066 vec = cls .__new__ (cls )
71- vec ._value = value
67+ vec ._value = list ( struct . unpack_from ( f'> { dim } e' , value [ 4 :]))
7268 return vec
7369
7470 @classmethod
0 commit comments