/*#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.
<pre>
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)
</pre>""")
*/
#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:
<pre>
vector rangeFill(vector(2, 2), 0) == vector(0, 1, 0, 1)
vector rangeFill(vector(2, 2), 1) == vector(0, 0, 1, 1)
</pre>
")
*/
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;
}
syntax highlighted by Code2HTML, v. 0.9.1