/*#io Vector ioDoc( docCopyright("Steve Dekorte", 2002) docLicense("BSD revised") docCategory("Math") docDescription(""" An object for fast operations on 1 dimensional arrays of single-precision floating point values. Vector processor acceleration is used for certain operations on some platforms.
Io> v1 := vector(1, 2, 3)                    
==> vector(1, 2, 3)
Io> v1 *= 2
==> vector(2, 4, 6)
Io> v1 += 1
==> vector(3, 5, 7)
Io> v1 -= 1
==> vector(2, 4, 6)
Io> v1 /= 2
==> vector(1, 2, 3)
Io> v1 += v1
==> vector(2, 4, 6)
""") */ #include "IoSeq.h" #include "IoState.h" #include "IoObject.h" #include "IoVector.h" #include "IoNumber.h" #define VIVAR(self) ((Vector *)(IoObject_dataPointer(self))) void *IoMessage_locals_vectorArgAt_(IoMessage *self, void *locals, int n) { IoObject *v = IoMessage_locals_valueArgAt_(self, locals, n); if (!ISVECTOR(v)) { IoMessage_locals_numberArgAt_errorForType_(self, locals, n, "Vector"); } return v; } void *IoMessage_locals_pointArgAt_(IoMessage *m, void *locals, int n) { IoVector *self = IoMessage_locals_vectorArgAt_(m, locals, n); IOASSERT(IoVector_rawSize(self) > 1, "Vector not long enough to be used as point argument"); return self; } IoTag *IoVector_tag(void *state) { IoTag *tag = IoTag_newWithName_("Vector"); tag->state = state; tag->cloneFunc = (TagCloneFunc *)IoVector_rawClone; //tag->markFunc = (TagMarkFunc *)IoVector_mark; tag->freeFunc = (TagFreeFunc *)IoVector_free; return tag; } IoVector* IoVector_proto(void *state) { IoMethodTable methodTable[] = { {"copy", IoVector_copy_}, {"subarray", IoVector_subarray}, {"size", IoVector_size}, {"setSize", IoVector_setSize_}, {"at", IoVector_at_}, {"atPut", IoVector_at_put_}, {"asBuffer", IoVector_asBuffer}, {"==", IoVector_equals}, {"+=", IoVector_plusEquals}, {"+", IoVector_plus}, {"-=", IoVector_minusEquals}, {"-", IoVector_minus}, {"*=", IoVector_multiplyEquals}, {"*", IoVector_multiply}, {"/=", IoVector_divideEquals}, {"/", IoVector_divide}, {"dot", IoVector_dotProduct}, {"sum", IoVector_sum}, {"min", IoVector_min}, {"max", IoVector_max}, {"mean", IoVector_mean}, {"square", IoVector_square}, {"meanSquare", IoVector_meanSquare}, {"rootMeanSquare", IoVector_rootMeanSquare}, {"normalize", IoVector_normalize}, {"absolute", IoVector_absolute}, {"abs", IoVector_absolute}, {"log", IoVector_log}, {"log10", IoVector_log10}, {"pow", IoVector_pow}, {"random", IoVector_random}, {"sort", IoVector_sort}, {"reverseSort", IoVector_reverseSort}, {"setMin", IoVector_setMin_}, {"setMax", IoVector_setMax_}, {"set", IoVector_set_}, {"setAll", IoVector_setAll_}, {"sin", IoVector_sin}, /* -------------------------- */ {"x", IoVector_x}, {"y", IoVector_y}, {"z", IoVector_z}, {"width", IoVector_x}, {"height", IoVector_y}, {"depth", IoVector_z}, {"setX", IoVector_setX}, {"setY", IoVector_setY}, {"setZ", IoVector_setZ}, {"setWidth", IoVector_setX}, {"setHeight", IoVector_setY}, {"setDepth", IoVector_setZ}, {"zero", IoVector_zero}, {"sign", IoVector_sign}, {"negate", IoVector_negate}, {"<=", IoVector_lessThanOrEqualTo}, {">=", IoVector_greaterThanOrEqualTo}, {"cross", IoVector_cross}, {"ceil", IoVector_ceil}, {"floor", IoVector_floor}, {"distanceTo", IoVector_distanceTo}, //{"print", IoVector_print}, {"Min", IoVector_Min}, {"Max", IoVector_Max}, {"zero", IoVector_zero}, {"isZero", IoVector_isZero}, {"sign", IoVector_sign}, {"rangeFill", IoVector_rangeFill}, {NULL, NULL} }; IoObject *self = IoObject_new(state); self->tag = IoVector_tag(state); IoObject_setDataPointer_(self, Vector_new()); IoState_registerProtoWithFunc_(state, self, IoVector_proto); IoObject_addMethodTable_(self, methodTable); return self; } IoVector* IoVector_rawClone(IoVector *proto) { IoObject *self = IoObject_rawClonePrimitive(proto); IoObject_setDataPointer_(self, Vector_clone(VIVAR(proto))); return self; } IoVector *IoVector_new(void *state) { IoObject *proto = IoState_protoWithInitFunction_(state, IoVector_proto); return IOCLONE(proto); } IoVector *IoVector_newWithSize_(void *state, size_t size) { IoVector *self = IoVector_new(state); Vector_setSize_(VIVAR(self), size); return self; } IoVector *IoVector_newX_y_z_(void *state, NUM_TYPE x, NUM_TYPE y, NUM_TYPE z) { IoVector *self = IoVector_new(state); Vector_setXYZ(VIVAR(self), x, y, z); return self; } IoVector *IoVector_newWithRawVector_(void *state, Vector *vec) { IoVector *proto = IoState_protoWithInitFunction_(state, IoVector_proto); IoVector *self = IOCLONE(proto); IoObject_setDataPointer_(self, (Vector *)vec); return self; } void IoVector_setVector_(IoVector *self, Vector *na) { if (VIVAR(self) != na) Vector_free(VIVAR(self)); IoObject_setDataPointer_(self, (Vector *)na); } Vector *IoVector_rawVector(IoVector *self) { return VIVAR(self); } PointData *IoVector_rawPointData(IoVector *self) { return Vector_pointData(VIVAR(self)); } void IoVector_free(IoVector *self) { Vector_free(VIVAR(self)); } IoObject *IoVector_size(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("size", "Returns the number of elements in the receiver.") */ return IONUMBER(Vector_size(VIVAR(self))); } size_t IoVector_rawSize(IoVector *self) { return Vector_size(VIVAR(self)); } IoObject *IoVector_setSize_(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("setSize(aNumber)", "Sets the number of elements in the receiver. Returns self.") */ int n = IoMessage_locals_intArgAt_(m, locals, 0); Vector_setSize_(VIVAR(self), n); return self; } IoVector *IoVector_rawCopy(IoVector *self, IoVector *other) { Vector_copy_(VIVAR(self), VIVAR(other)); return self; } void IoVector_rawSetXYZ(IoVector *self, NUM_TYPE x, NUM_TYPE y, NUM_TYPE z) { Vector_setXYZ(VIVAR(self), x, y, z); } void IoVector_rawGetXYZ(IoVector *self, NUM_TYPE *x, NUM_TYPE *y, NUM_TYPE *z) { Vector_getXYZ(VIVAR(self), x, y, z); } IoSeq *IoVector_asBuffer(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("asBuffer", "Returns the elements of the vector as a buffer of floating point values in the current architecture's byte order and float format.") */ return IoSeq_newWithData_length_(IOSTATE, Vector_bytes(VIVAR(self)), Vector_sizeInBytes(VIVAR(self))); } IoSeq *IoVector_equals(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("==(aVector)", "Returns true if all elements of aVector are equal to those of the receiver. Returns false otherwise.") */ IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0); if (ISVECTOR(other)) { Vector *v1 = VIVAR(self); Vector *v2 = VIVAR(other); int e = Vector_equals_(v1, v2); return IOBOOL(self, e); } return IOFALSE(self); } IoObject *IoVector_copy_(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("copy(aVectorOrBuffer)", "Sets the size of the receiver to match that of aVector and copies all elements of aVector to the receiver. If the argument is a Buffer, it will copy it's data, leaving any remaining bytes set to zero.") */ IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0); if (ISVECTOR(other)) { Vector_copy_(VIVAR(self), VIVAR(other)); } else if (ISSEQ(other)) { ByteArray *ba = IoSeq_rawByteArray(other); Vector_copyData_length_(VIVAR(self), ByteArray_bytes(ba), ByteArray_size(ba)); } else { IoState_error_(IOSTATE, m, "Vector += requires Vector or Number argument"); } return self; } IoObject *IoVector_subarray(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("subarray(startIndex, length)", "Returns a new Vector containing the elements from startIndex to startIndex + length.") */ int start = IoMessage_locals_intArgAt_(m, locals, 0); int length = IoMessage_locals_intArgAt_(m, locals, 1); Vector *a = Vector_subarray_(VIVAR(self), start, length); if (a) { IoVector *ioa = IoVector_new(IOSTATE); IoVector_setVector_(ioa, a); return ioa; } return IONIL(self); } IoObject *IoVector_at_(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("at(indexNumber)", "Returns a Number containing the value of the receivers element at indexNumber.") */ int n = IoMessage_locals_intArgAt_(m, locals, 0); double d = (double)Vector_at_(VIVAR(self), n); return IONUMBER(d); } IoObject *IoVector_at_put_(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("atPut(indexNumber, numberValue)", "Puts numberValue into the element at indexNumber. Expands the size of the vector if needed.") */ size_t n = IoMessage_locals_longArgAt_(m, locals, 0); double d = IoMessage_locals_doubleArgAt_(m, locals, 1); Vector_at_put_(VIVAR(self), n, (NUM_TYPE)d); return self; } /* --- math -------------------------------------------- */ IoObject *IoVector_plusEquals(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("+=(aValue)", "If aValue is a Number, an in-place scalar addition is performed on the receiver. If aValue is a vector, an in-place vector addition is performed on the receiver. Otherwise, a 'Vector +=' exception is raised. Returns self.") */ IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0); if (IoMessage_argCount(m) > 1) { long index = IoMessage_locals_longArgAt_(m, locals, 1); float xscale = IoMessage_locals_floatArgAt_(m, locals, 2); float yscale = IoMessage_locals_floatArgAt_(m, locals, 3); Vector_addArray_at_xscale_yscale_(VIVAR(self), VIVAR(other), index, xscale, yscale); } else if (ISVECTOR(other)) { Vector_addArray_(VIVAR(self), VIVAR(other)); } else if (ISNUMBER(other)) { Vector_addScalar_(VIVAR(self), CNUMBER(other)); } else { IoState_error_(IOSTATE, m, "Vector += requires Vector or Number argument"); } return self; } IoObject *IoVector_plus(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("+(aValue)", "Same as: receiver clone +=(aValue)") */ IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0); Vector *vec = Vector_new(); Vector_copy_(vec, VIVAR(self)); /* IOASSERT(IoVector_rawSize(self) == IoVector_rawSize(other), "Vectors not of equal size"); */ if (ISVECTOR(other)) { Vector_addArray_(vec, VIVAR(other)); } else if (ISNUMBER(other)) { Vector_addScalar_(vec, CNUMBER(other)); } else { IoState_error_(IOSTATE, m, "Vector + requires Vector or Number argument"); } return IOVECTOR(vec); } IoObject *IoVector_minusEquals(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("-=(aValue)", "If aValue is a Number, an in-place scalar subtraction is performed on the receiver. If aValue is a vector, an in-place vector subtraction is performed on the receiver. Otherwise, a Vector -= exception is raised. Returns self.") */ IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0); if (ISVECTOR(other)) { Vector_subtractArray_(VIVAR(self), VIVAR(other)); } else if (ISNUMBER(other)) { Vector_subtractScalar_(VIVAR(self), CNUMBER(other)); } else { IoState_error_(IOSTATE, m, "Vector -= requires Vector or Number argument"); } return self; } IoObject *IoVector_minus(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("-(aValue)", "Same as: receiver clone -=(aValue)") */ IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0); Vector *vec = Vector_new(); Vector_copy_(vec, VIVAR(self)); if (ISVECTOR(other)) { Vector_subtractArray_(vec, VIVAR(other)); } else if (ISNUMBER(other)) { Vector_subtractScalar_(vec, CNUMBER(other)); } else { IoState_error_(IOSTATE, m, "Vector vectorSubtracting requires Vector or Number argument"); } return IOVECTOR(vec); } IoObject *IoVector_multiplyEquals(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("*=(aValue)", "If aValue is a Number, each element of the receiver is replaced by the product of it's value with aValue. If aValue is a vector, each element of the receiver is replaced by the product it's value with the element at the same index in the aValue vector. Returns self.") */ IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0); if (ISVECTOR(other)) { Vector_multiplyArray_(VIVAR(self), VIVAR(other)); } else if (ISNUMBER(other)) { Vector_multiplyScalar_(VIVAR(self), CNUMBER(other)); } else { IoState_error_(IOSTATE, m, "Vector multiply requires Vector or Number argument"); } return self; } IoObject *IoVector_multiply(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("*(aValue)", "Same as: receiver clone *=(aValue)") */ IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0); Vector *vec = Vector_new(); Vector_copy_(vec, VIVAR(self)); if (ISVECTOR(other)) { Vector_multiplyArray_(vec, VIVAR(other)); } else if (ISNUMBER(other)) { Vector_multiplyScalar_(vec, CNUMBER(other)); } else { IoState_error_(IOSTATE, m, "Vector vectorMultiplying requires Vector or Number argument"); } return IOVECTOR(vec); } IoObject *IoVector_divideEquals(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("*=(aValue)", "If aValue is a Number, each element of the receiver is replaced by the it's value divided by aValue. If aValue is a vector, each element of the receiver is replaced by the product it's value divided by the element at the same index in the aValue vector. Returns self.") */ IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0); if (ISVECTOR(other)) { Vector_divideArray_(VIVAR(self), VIVAR(other)); } else if (ISNUMBER(other)) { Vector_divideScalar_(VIVAR(self), CNUMBER(other)); } else { IoState_error_(IOSTATE, m, "Vector divide requires Vector or Number argument"); } return self; } IoObject *IoVector_divide(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("/(aValue)", "Same as: receiver clone /=(aValue)") */ IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0); Vector *vec = Vector_new(); Vector_copy_(vec, VIVAR(self)); if (ISVECTOR(other)) { Vector_divideArray_(vec, VIVAR(other)); } else if (ISNUMBER(other)) { Vector_divideScalar_(vec, CNUMBER(other)); } else { IoState_error_(IOSTATE, m, "Vector vectorDividing requires Vector or Number argument"); } return IOVECTOR(vec); } IoObject *IoVector_dotProduct(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("dotProduct(aVector)", "Same as '(receiver + aVector) sum', although the implementation is much faster.") */ IoObject *other = IoMessage_locals_vectorArgAt_(m, locals, 0); double r = Vector_dotProduct_(VIVAR(self), VIVAR(other)); return IONUMBER(r); } IoObject *IoVector_sum(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("sum", "Returns the sum of all elements of the receiver.") */ return IONUMBER(Vector_sum(VIVAR(self))); } IoObject *IoVector_min(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("min", "Returns the element of the vector with the lowest value.") */ return IONUMBER(Vector_min(VIVAR(self))); } IoObject *IoVector_max(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("max", "Returns the element of the vector with the greatest value.") */ return IONUMBER(Vector_max(VIVAR(self))); } IoObject *IoVector_mean(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("mean", "Same as 'receiver sum / receiver size'.") */ return IONUMBER(Vector_mean(VIVAR(self))); } IoObject *IoVector_square(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("squares", "Each element of the vector is squared. Returns self.") */ Vector_square(VIVAR(self)); return self; } IoObject *IoVector_normalize(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("normalize", "Same as 'receiver /= receiver sum', but with a faster implementation. Returns self.") */ Vector_normalize(VIVAR(self)); return self; } IoObject *IoVector_absolute(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("absolute", "Each element of the receiver is replaced with it's absolute value. Returns self.") */ Vector_absolute(VIVAR(self)); return self; } IoObject *IoVector_log(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("log", "Each element of the receiver is replaced with it's natural log value. Returns self.") */ Vector_log(VIVAR(self)); return self; } IoObject *IoVector_log10(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("log10", "Each element of the receiver is replaced with it's log base 10 value. Returns self.") */ Vector_log10(VIVAR(self)); return self; } IoObject *IoVector_pow(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("pow(aNumber)", "Each element of the receiver is replaced with it's value taken to the power of aNumber. Returns self.") */ int p = IoMessage_locals_intArgAt_(m, locals, 0); Vector_pow(VIVAR(self), p); return self; } IoObject *IoVector_random(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("random(minNumber, maxNumber)", "Each element of the receiver is replaced with random value between minNumber and maxNumber. Returns self.") */ int min = IoMessage_locals_intArgAt_(m, locals, 0); int max = IoMessage_locals_intArgAt_(m, locals, 1); Vector_random(VIVAR(self), min, max); return self; } IoObject *IoVector_sort(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("sort", "The elements of the receiver are sorted from smallest to greatest. Returns self.") */ Vector_sort(VIVAR(self)); return self; } IoObject *IoVector_reverseSort(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("reverseSort", "The elements of the receiver are sorted from greatest to smallest. Returns self.") */ Vector_reverseSort(VIVAR(self)); return self; } IoObject *IoVector_meanSquare(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("meanSquare", "Same as 'receiver clone square sum / receiver size'.") */ return IONUMBER(Vector_meanSquare(VIVAR(self))); } IoObject *IoVector_rootMeanSquare(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("rootMeanSquare", "Same as 'receiver meanSquare squareRoot' ") */ return IONUMBER(Vector_rootMeanSquare(VIVAR(self))); } IoObject *IoVector_setMin_(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("setMin(aNumber)", "Sets all elements of the receiver that are less than aNumber to aNumber. Returns self.") */ double v = IoMessage_locals_doubleArgAt_(m, locals, 0); Vector_setMin_(VIVAR(self), v); return self; } IoObject *IoVector_setMax_(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("setMax(aValue)", "Sets all elements of the receiver that are greater than aNumber to aNumber. Returns self.") */ double v = IoMessage_locals_doubleArgAt_(m, locals, 0); Vector_setMax_(VIVAR(self), v); return self; } IoObject *IoVector_set_(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("set(value1, value2, ...)", "Sets the elements of the array to the value of the arguments. Returns self.") */ int i, max = IoMessage_argCount(m); Vector *vec = VIVAR(self); for (i = 0; i < max; i ++) { float v = IoMessage_locals_doubleArgAt_(m, locals, i); Vector_at_put_(vec, i, v); } return self; } IoObject *IoVector_setAll_(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("setAll(aNumber)", "Sets all elements of the receiver to aNumber.") */ double v = IoMessage_locals_doubleArgAt_(m, locals, 0); Vector_set_(VIVAR(self), v); return self; } IoObject *IoVector_sin(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("sin", "Sets all elements to the sin of their value. Returns self.") */ Vector_sin(VIVAR(self)); return self; } IoObject *IoVector_x(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("x", "Same as 'receiver at(0)' ") */ /*#io docSlot("width", "Same as 'receiver at(0)'") */ Vector *vec = VIVAR(self); IOASSERT(Vector_size(vec) > 0, "Vector missing element at index 0"); return IONUMBER(Vector_at_(vec, 0)); } IoObject *IoVector_y(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("y", "Same as 'receiver at(1)'") */ /*#io docSlot("height", "Same as 'receiver at(1)'") */ Vector *vec = VIVAR(self); IOASSERT(Vector_size(vec) > 1, "Vector missing element at index 1"); return IONUMBER(Vector_at_(vec, 1)); } IoObject *IoVector_z(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("z", "Same as 'receiver at(2)'") */ /*#io docSlot("depth", "Same as 'receiver at(2)'") */ Vector *vec = VIVAR(self); IOASSERT(Vector_size(vec) > 2, "Vector missing element at index 2"); return IONUMBER(Vector_at_(vec, 2)); } IoObject *IoVector_w(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("w", "Same as 'receiver at(3)'") */ Vector *vec = VIVAR(self); IOASSERT(Vector_size(vec) > 3, "Vector missing element at index 3"); return IONUMBER(Vector_at_(vec, 3)); } IoObject *IoVector_setX(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("setX(aValue)", "Same as 'receiver atPut(0, aValue)'") */ /*#io docSlot("setWidth(aValue)", "Same as 'receiver atPut(0, aValue)'") */ Vector *vec = VIVAR(self); double v = IoMessage_locals_doubleArgAt_(m, locals, 0); Vector_at_put_(vec, 0, (NUM_TYPE)v); return self; } IoObject *IoVector_setY(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("setY(aValue)", "Same as 'receiver atPut(0, aValue)'") */ /*#io docSlot("setHeight(aValue)", "Same as 'receiver atPut(0, aValue)'") */ Vector *vec = VIVAR(self); double v = IoMessage_locals_doubleArgAt_(m, locals, 0); Vector_at_put_(vec, 1, (NUM_TYPE)v); return self; } IoObject *IoVector_setZ(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("setZ(aValue)", "Same as: receiver atPut(0, aValue)") */ /*#io docSlot("setDepth(aValue)", "Same as: receiver atPut(0, aValue)") */ Vector *vec = VIVAR(self); double v = IoMessage_locals_doubleArgAt_(m, locals, 0); Vector_at_put_(vec, 2, (NUM_TYPE)v); return self; } IoObject *IoVector_setW(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("setW(aValue)", "Same as: receiver atPut(3, aValue)") */ Vector *vec = VIVAR(self); double v = IoMessage_locals_doubleArgAt_(m, locals, 3); Vector_at_put_(vec, 3, (NUM_TYPE)v); return self; } IoObject *IoVector_negate(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("negate", "Multiplies each element by -1. Returns self.") */ Vector *vec = VIVAR(self); Vector_negate(vec); return self; } IoObject *IoVector_lessThanOrEqualTo(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("<=(aValue)", "If aValue is a Vector, true is returned if each element of the receiver is less than or equal to the corresponding element in aValue or Nil is returned otherwise. If aValue is a Number, then self is returned if all elements of the receiver are less than aValue or false otherwise. If aValue is niether a Number or a Vector, an exception is raised.") */ IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0); Vector *vec = VIVAR(self); if (ISVECTOR(other)) { Vector *vec2 = VIVAR(other); //IOASSERT(Vector_size(vec) == Vector_size(vec2), "Vectors not of equal size"); return IOBOOL(self, Vector_lessThanOrEqualTo_(vec, vec2)); } if (ISNUMBER(other)) { return IOBOOL(self, Vector_lessThanOrEqualToScalar_(vec, CNUMBER(other))); } else { IoState_error_(IOSTATE, m, "Vector <= requires Vector or Number argument"); } return self; } IoObject *IoVector_greaterThanOrEqualTo(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot(">=(aValue)", "If aValue is a Vector, self is returned if each element of the receiver is greater than or equal to the corresponding element in aValue or Nil is returned otherwise. If aValue is a Number, then self is returned if all elements of the receiver are greater than aValue or false otherwise. If aValue is niether a Number or a Vector, an exception is raised.") */ IoObject *other = IoMessage_locals_valueArgAt_(m, locals, 0); Vector *vec = VIVAR(self); if (ISVECTOR(other)) { Vector *vec2 = VIVAR(other); //IOASSERT(Vector_size(vec) == Vector_size(vec2), "Vectors not of equal size"); return IOBOOL(self, Vector_greaterThanOrEqualTo_(vec, vec2)); } if (ISNUMBER(other)) { return IOBOOL(self, Vector_greaterThanOrEqualToScalar_(vec, CNUMBER(other))); } else { IoState_error_(IOSTATE, m, "Vector <= requires Vector or Number argument"); } return self; } IoObject *IoVector_cross(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("cross(aVector)", "Sets the receiver to the cross product of itself with aVector. Returns self.") */ IoVector *other = IoMessage_locals_vectorArgAt_(m, locals, 0); Vector *vec = VIVAR(self); Vector *vec2 = VIVAR(other); IOASSERT(Vector_size(vec) < 4, "Vectors must be of size < 4"); IOASSERT(Vector_size(vec) == Vector_size(vec2), "Vectors not of equal size"); Vector_crossProduct_(vec, vec2); return self; } IoObject *IoVector_ceil(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("ceil", "Applies the ceil operator to each element of the receiver. Return self.") */ Vector *vec = VIVAR(self); Vector_ceil(vec); return self; } IoObject *IoVector_floor(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("floor", "Applies the floor operator to each element of the receiver. Return self.") */ Vector *vec = VIVAR(self); Vector_floor(vec); return self; } IoObject *IoVector_distanceTo(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("distanceTo(aVector)", "Returns the distance from the receiver to aVector.") */ IoVector *other = IoMessage_locals_vectorArgAt_(m, locals, 0); Vector *vec = VIVAR(self); Vector *vec2 = VIVAR(other); IOASSERT(Vector_size(vec) == Vector_size(vec2), "Vectors not of equal size"); return IONUMBER(Vector_distanceTo_(vec, vec2)); } IoObject *IoVector_Min(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("Min(aVector)", "Sets each element of the receiver to be the lesser of itself and the corresponding element of aVector.") */ IoVector *other = IoMessage_locals_vectorArgAt_(m, locals, 0); Vector *vec = VIVAR(self); Vector *vec2 = VIVAR(other); IOASSERT(Vector_size(vec) == Vector_size(vec2), "Vectors not of equal size"); Vector_Min(vec, vec2); return self; } IoObject *IoVector_Max(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("Max(aVector)", "Sets each element of the receiver to be the greater of itself and the corresponding element of aVector.") */ IoVector *other = IoMessage_locals_vectorArgAt_(m, locals, 0); Vector *vec = VIVAR(self); Vector *vec2 = VIVAR(other); IOASSERT(Vector_size(vec) == Vector_size(vec2), "Vectors not of equal size"); Vector_Max(vec, vec2); return self; } IoObject *IoVector_zero(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("zero", "Sets each element of the receiver to zero.") */ Vector *vec = VIVAR(self); Vector_zero(vec); return self; } IoObject *IoVector_isZero(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("isZero", "Returns true if all elements of the receiver are zero, false otherwise.") */ Vector *vec = VIVAR(self); return IOBOOL(self, Vector_isZero(vec)); } IoObject *IoVector_sign(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("sign", "Sets each element to -1 if it is below zero, or 1 if it is above 0.") */ Vector *vec = VIVAR(self); Vector_sign(vec); return self; } IoObject *IoVector_print(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("print", "Prints a human readable representation of the receiver to standard output.") */ Vector_print(VIVAR(self)); return self; } IoObject *IoVector_rangeFill(IoVector *self, IoObject *locals, IoMessage *m) { /*#io docSlot("rangeFill(shapeVector, indexDimension)", "Set the values of the array to the their index values for the indexDimension given the specified shapeVector. The array will be resized to a size that is the product of the shapeVector. Examples:
 vector rangeFill(vector(2, 2), 0) == vector(0, 1, 0, 1)
 vector rangeFill(vector(2, 2), 1) == vector(0, 0, 1, 1)
 
") */ if(IoMessage_argCount(m) == 0) { Vector_rangeFill(VIVAR(self)); } else { IoVector *other = IoMessage_locals_vectorArgAt_(m, locals, 0); size_t d = IoMessage_locals_intArgAt_(m, locals, 1); Vector_rangeFillWithShapeVectorDim(VIVAR(self), VIVAR(other), d); } return self; }