DIRECTORY PriorityQueue USING[Ref, Predict, Insert, Empty, Remove], Real USING[FixI, RoundI], RealVec USING[Handle, Object]; RealVecImpl: MONITOR -- protects sortee IMPORTS PriorityQueue, Real EXPORTS RealVec = { OPEN RealVec; LengthFault: PUBLIC ERROR[vec: Handle, expectedLength: NAT] = CODE; Smooth: PUBLIC PROC[h: Handle, nElements: NAT] RETURNS[ans: Handle] = { IF nElements = h.length THEN RETURN[h]; ans _ NEW[Object[nElements]]; FOR j: NAT IN [0..nElements) DO x: REAL = j; startT: REAL _ x / nElements; endT: REAL _ (x + 1.0) / nElements; a: NAT _ Real.FixI[startT * h.length]; b: NAT _ Real.RoundI[endT * h.length]; -- may be too small by 1 dtOld: REAL _ 1.0/h.length; dtNew: REAL _ endT - startT; IF b*dtOld < endT THEN b _ b + 1; IF a = b THEN ERROR; ans.elements[j] _ 0.0; FOR z: NAT IN [a..b) -- left edge index (from 0) identifies the bucket DO --add in the value in the zth bucket times the fraction of the time ans.elements[j] _ ans.elements[j] + h.elements[z] -- the value in the zth bucket * (MIN[dtOld, MIN[endT, (z + 1)*dtOld] - MAX[startT, z*dtOld]])/dtNew ENDLOOP; ENDLOOP}; All: PUBLIC PROC[length: NAT, value: REAL _ 0.0] RETURNS[ans: Handle] = {ans _ NEW[Object[length]]; FOR i: NAT IN [0..length) DO ans.elements[i] _ value ENDLOOP}; IndexVec: PUBLIC PROC[length: NAT] RETURNS[ans: Handle] = {ans _ NEW[Object[length]]; FOR i: NAT IN [0..length) DO ans.elements[i] _ i ENDLOOP}; SubVec: PUBLIC PROC[h: Handle, firstIndex, lastIndex: NAT] RETURNS[ans: Handle] = {length: NAT _ (IF h = NIL THEN 0 ELSE h.length); IF lastIndex < firstIndex OR h = NIL OR lastIndex >= h.length THEN ERROR LengthFault[h, length]; length _ lastIndex - firstIndex + 1; ans _ NEW[Object[length]]; FOR i: NAT IN [0..length) DO ans.elements[i] _ h.elements[firstIndex + i] ENDLOOP}; ConCat: PUBLIC PROC[h1, h2: Handle] RETURNS[ans: Handle] = { length: NAT; IF h1 = NIL OR h2 = NIL THEN ERROR LengthFault[NIL, 0]; IF LOOPHOLE[LOOPHOLE[h1.length, CARDINAL] + LOOPHOLE[h2.length, CARDINAL], INTEGER] < 0 THEN ERROR LengthFault[NIL, 0]; -- overflow check length _ h1.length + h2.length; ans _ NEW[Object[length]]; FOR i: NAT IN [0..h1.length) DO ans.elements[i] _ h1.elements[i] ENDLOOP; FOR i: NAT IN [0..h2.length) DO ans.elements[h1.length + i] _ h2.elements[i] ENDLOOP}; Permute: PUBLIC PROC[h: Handle, perms: Handle] RETURNS[ans: Handle] = { length: NAT _ perms.length; ans _ NEW[Object[length]]; FOR i: NAT IN [0..length) DO x: NAT = Real.FixI[perms.elements[i]]; IF x >= h.length THEN ERROR LengthFault[h, x+1]; ans.elements[i] _ h.elements[x]; ENDLOOP; }; sortee: Handle; sortPred: SAFE PROC[x, y: REF ANY, data: REF ANY] RETURNS[BOOLEAN] = TRUSTED {i: NAT = LOOPHOLE--NARROW--[x, REF NAT]^; j: NAT = LOOPHOLE--NARROW--[y, REF NAT]^; RETURN[sortee.elements[i] < sortee.elements[j]]}; SortOrder: PUBLIC ENTRY PROC[h: Handle] RETURNS[perms: Handle] = {ENABLE UNWIND => NULL; length: NAT _ h.length; q: PriorityQueue.Ref; sortee _ h; q _ PriorityQueue.Predict[pred: sortPred, size: h.length]; perms _ NEW[Object[length]]; FOR i: NAT IN [0..h.length) DO PriorityQueue.Insert[q, NEW[NAT _ i]] ENDLOOP; FOR i: NAT IN [0..h.length) DO perms.elements[i] _ NARROW[PriorityQueue.Remove[q], REF NAT]^ ENDLOOP; IF NOT PriorityQueue.Empty[q] THEN ERROR; }; Add: PUBLIC PROC[h1, h2: Handle] RETURNS[ans: Handle] = { length: NAT; IF h1 = NIL OR h2 = NIL THEN ERROR LengthFault[NIL, 0]; IF h1.length # h2.length THEN ERROR LengthFault[h2, h1.length]; length _ h1.length; ans _ NEW[Object[length]]; FOR i: NAT IN [0..length) DO ans.elements[i] _ h1.elements[i] + h2.elements[i] ENDLOOP}; Subtract: PUBLIC PROC[h1, h2: Handle] RETURNS[ans: Handle] = { length: NAT; IF h1 = NIL OR h2 = NIL THEN ERROR LengthFault[NIL, 0]; IF h1.length # h2.length THEN ERROR LengthFault[h2, h1.length]; length _ h1.length; ans _ NEW[Object[length]]; FOR i: NAT IN [0..length) DO ans.elements[i] _ h1.elements[i] - h2.elements[i] ENDLOOP}; Multiply: PUBLIC PROC[h1, h2: Handle] RETURNS[ans: Handle] = { length: NAT; IF h1 = NIL OR h2 = NIL THEN ERROR LengthFault[NIL, 0]; IF h1.length # h2.length THEN ERROR LengthFault[h2, h1.length]; length _ h1.length; ans _ NEW[Object[length]]; FOR i: NAT IN [0..length) DO ans.elements[i] _ h1.elements[i] * h2.elements[i] ENDLOOP}; Divide: PUBLIC PROC[h1, h2: Handle] RETURNS[ans: Handle] = { length: NAT; IF h1 = NIL OR h2 = NIL THEN ERROR LengthFault[NIL, 0]; IF h1.length # h2.length THEN ERROR LengthFault[h2, h1.length]; length _ h1.length; ans _ NEW[Object[length]]; FOR i: NAT IN [0..length) DO ans.elements[i] _ h1.elements[i] / h2.elements[i] ENDLOOP}; DotProduct: PUBLIC PROC[h1, h2: Handle] RETURNS[ans: REAL] = { length: NAT; IF h1 = NIL OR h2 = NIL THEN ERROR LengthFault[NIL, 0]; IF h1.length # h2.length THEN ERROR LengthFault[h2, h1.length]; length _ h1.length; ans _ 0.0; FOR i: NAT IN [0..length) DO ans _ ans + h1.elements[i] * h2.elements[i] ENDLOOP}; ScalarAdd: PUBLIC PROC[h: Handle, s: REAL] RETURNS[ans: Handle] = { length: NAT; IF h = NIL THEN RETURN[NIL]; length _ h.length; ans _ NEW[Object[length]]; FOR i: NAT IN [0..length) DO ans.elements[i] _ h.elements[i] + s ENDLOOP}; ScalarSubtract: PUBLIC PROC[h: Handle, s: REAL] RETURNS[ans: Handle] = { length: NAT; IF h = NIL THEN RETURN[NIL]; length _ h.length; ans _ NEW[Object[length]]; FOR i: NAT IN [0..length) DO ans.elements[i] _ h.elements[i] - s ENDLOOP}; ScalarMultiply: PUBLIC PROC[h: Handle, s: REAL] RETURNS[ans: Handle] = { length: NAT; IF h = NIL THEN RETURN[NIL]; length _ h.length; ans _ NEW[Object[length]]; FOR i: NAT IN [0..length) DO ans.elements[i] _ h.elements[i] * s ENDLOOP}; ScalarDivide: PUBLIC PROC[h: Handle, s: REAL] RETURNS[ans: Handle] = { length: NAT; IF h = NIL THEN RETURN[NIL]; length _ h.length; ans _ NEW[Object[length]]; FOR i: NAT IN [0..length) DO ans.elements[i] _ h.elements[i] / s ENDLOOP}; Equal: PUBLIC PROC[h1, h2: Handle] RETURNS[BOOLEAN] = { IF h1 = NIL OR h2 = NIL THEN RETURN[h1 = h2]; FOR i: NAT IN [0..h1.length) DO IF NOT almost[h1.elements[i], h2.elements[i]] THEN RETURN[FALSE] ENDLOOP; RETURN[TRUE]}; almost: PROC[p, q: REAL] RETURNS[BOOLEAN] = INLINE {RETURN[MAX[p, q] = 0.0 OR ABS[p - q]/MAX[p, q] < 0.00001]}; }. HRealVecImpl.mesa, an implementation for dealing with vectors of real numbers Last Modified On December 16, 1983 2:00 pm By Paul Rovner PUBLIC SIGNALS PUBLIC PROCs nElements <= h.length. Result has averaged values as per some reasonable algorithm a, b, c... are in the old space, i, j, k ... in the new now add up the contributions of each old bucket that the new bucket overlaps value covered by the zth bucket in the new bucket convenient constructors h[0] = 0, h[n] = n convenient composition and extraction operations h.elements[FixI[perms.elements[i]]] is put into ans.elements[i] e.g., Permute[h, SortOrder[h]] produces a sorted version of h perms[i] is the index in h of the ith smallest element i.e. (h.elements[perms[i]] <= h.elements[perms[i+1]]) element-by-element operations scalar element-by-element operations Ê è˜JšœL™LJšœ9™9J˜šÏk ˜ Jšœœ&˜9Jšœœ˜Jšœœ˜J˜—šœ œÏc˜(Jšœ˜Jšœ ˜Jšœœ ˜J˜—šœ™Jš œ œœœœ˜CJ˜—šœ ™ Jšœ™Jšœ;™;š Ïnœœœœœ˜Ešœœœœ˜)Jšœ7™7Jšœœ˜šœœœ˜š˜Jšœœ˜ Jšœœ˜Jšœœ˜#Jšœœ ˜&Jšœœ"ž˜@Jšœœ˜Jšœœ˜Jšœœ ˜!Jšœœœ˜˜JšœC™CJšœ™—šœœœ ž1˜GJšœ™šœžC˜FJšœ+™+˜!šœž˜/šœœœ˜&Jšœœ˜————Jšœ˜———Jšœ˜ J˜—Jšœ™—š Ÿœœœ œ œœ˜Gšœœ˜Jš œœœ œœ˜>J˜—Jšœ™—š Ÿœœœ œœ˜9šœœ˜Jš œœœ œœ˜;J˜—Jšœ2™2—šŸœœœ#œ˜:Jšœ˜š œ œœœœœ ˜1šœœœœ˜=Jšœœ˜"—J˜$Jšœœ˜šœœœ ˜Jšœ.œ˜:J˜———šŸœœœœ˜:šœ œ˜Jšœœœœœœ œ˜7šœœœ œ˜)Jšœœ œœ˜-Jšœœ œž˜2—J˜Jšœœ˜šœœœ˜Jšœ"œ˜,—šœœœ˜Jšœ.œ˜9J˜——JšœB™BJšœ=™=—šŸœœœœ˜Ešœ œ˜Jšœœ˜šœœœ ˜šœœ ˜)Jšœœœ˜0J˜ —Jšœ˜——J˜J˜—J˜š œ œœœœœœ˜1Jšœœ˜š œœž œœœ˜*Jš œœž œœœ˜)Jšœ+˜1J˜—Jšœ6™6Jšœ5™5—š Ÿ œœœœ œ˜@šœœœœ˜Jšœœ ˜J˜J˜ J˜:J˜Jšœœ˜šœœœ˜Jšœœœœ˜1—šœœœ˜Jšœœœœ˜@Jšœ˜—Jšœœœœ˜)—J˜J˜Jšœ™—šŸœœœœ˜7šœ œ˜Jšœœœœœœ œ˜7Jšœœœ˜?J˜Jšœœ˜šœœœ ˜Jšœ3œ˜>J˜———šŸœœœœ˜<šœ œ˜Jšœœœœœœ œ˜7Jšœœœ˜?J˜Jšœœ˜šœœœ ˜Jšœ3œ˜>J˜———šŸœœœœ˜<šœ œ˜Jšœœœœœœ œ˜7Jšœœœ˜?J˜Jšœœ˜šœœœ ˜Jšœ3œ˜>J˜———šŸœœœœ˜:šœ œ˜Jšœœœœœœ œ˜7Jšœœœ˜?J˜Jšœœ˜šœœœ ˜Jšœ3œ˜>J˜———š Ÿ œœœœœ˜<šœ œ˜Jšœœœœœœ œ˜7Jšœœœ˜?J˜J˜ šœœœ ˜Jšœ-œ˜8J˜J˜——Jšœ&™&—š Ÿ œœœœœ˜Ašœ œ˜Jš œœœœœ˜J˜Jšœœ˜šœœœ ˜Jšœ%œ˜0J˜———š Ÿœœœœœ˜Fšœ œ˜Jš œœœœœ˜J˜Jšœœ˜šœœœ ˜Jšœ%œ˜0J˜———š Ÿœœœœœ˜Fšœ œ˜Jš œœœœœ˜J˜Jšœœ˜šœœœ ˜Jšœ%œ˜0J˜———š Ÿ œœœœœ˜Dšœ œ˜Jš œœœœœ˜J˜Jšœœ˜šœœœ ˜Jšœ%œ˜0J˜———š Ÿœœœœœ˜5š œœœœœœœ ˜/šœœœ˜šœœœ'˜0Jšœœœ˜—Jšœ˜—Jšœœ˜J˜———š œ œœœœ˜4Jš œœœ œœœ˜