#include "cakit.h"
#define VAL_MIN -32500
#define VAL_MAX +32500
static int
bigintobj_check (bigintobj_t self, bigintobj_args args)
{
assert (args.proto);
[args.proto check];
assert (VAL_MIN == -VAL_MAX); /* for opposite tests */
assert (VAL_MAX * VAL_MAX + VAL_MAX * VAL_MAX < INT_MAX);
assert (VAL_MIN * VAL_MAX - VAL_MIN * VAL_MAX > INT_MIN);
if (self->hit)
{
assert (VAL_MIN <= self->val && self->val <= VAL_MAX);
if (self->obj)
{
id obj = [args.proto intValue:self->val];
assert ([obj isEqual:self->obj]);
}
}
else
{
int val;
id obj = self->obj;
assert ([obj check]);
val = [obj intValue];
assert (val < VAL_MIN || VAL_MAX < val);
}
return 1;
}
/*
* return new reference to object or create it if necessary
*/
static id
bigintobj_obj (bigintobj_t self, bigintobj_args args)
{
assert (bigintobj_check (self, args));
if (self->obj)
{
return self->obj;
}
else
{
id obj;
assert (self->hit);
obj = [args.proto intValue:self->val];
assert ([obj intValue] == self->val);
return obj;
}
}
/*
* works inplace on "self"; creates object if it doesn't exists; returns it.
*/
static id
bigintobj_makeobj (bigintobj_c * self, bigintobj_args args)
{
assert (bigintobj_check (self, args));
if (self->obj)
{
return self->obj;
}
else
{
assert (self->hit);
return self->obj = [args.proto intValue:self->val];
}
}
/*
* initializing "c" by object
*/
static void
bigintobj_ooobj (bigintobj_c * c, id obj, bigintobj_args args)
{
int val = [obj intValue];
if (VAL_MIN <= val && val <= VAL_MAX)
{
c->hit = 1;
c->val = val;
c->obj = obj;
}
else
{
c->hit = 0;
c->obj = obj;
}
assert (bigintobj_check (c, args));
}
/*
* replacing "c" by object result of inplace operation
* used like :
*
* bigintobj_makeobj(c,args);
* bigintobj_inobj(c,[c->obj negate],args)
*/
static void
bigintobj_inobj (bigintobj_c * c, id obj, bigintobj_args args)
{
int val = [obj intValue];
/* c->obj is invalid reference now... replace it by result inplace op
* we cannot check "c" here (as the object is invalid...)
*/
assert (c->obj != nil);
if (VAL_MIN <= val && val <= VAL_MAX)
{
c->hit = 1;
c->val = val;
c->obj = obj;
}
else
{
c->hit = 0;
c->obj = obj;
}
assert (bigintobj_check (c, args));
}
/*
* initializing "c" by int value
*/
static void
bigintobj_ooval (bigintobj_c * c, int val, bigintobj_args args)
{
if (VAL_MIN <= val && val <= VAL_MAX)
{
c->hit = 1;
c->val = val;
c->obj = nil;
}
else
{
c->hit = 0;
c->obj = [args.proto intValue:val];
}
assert (bigintobj_check (c, args));
}
/*
* replacing "c" by int value
*/
static void
bigintobj_inval (bigintobj_c * c, int val, bigintobj_args args)
{
assert (bigintobj_check (c, args));
if (VAL_MIN <= val && val <= VAL_MAX)
{
c->hit = 1;
c->val = val;
if (c->obj)
c->obj = nil;
}
else
{
c->hit = 0;
if (c->obj)
c->obj = nil;
c->obj = [args.proto intValue:val];
}
assert (bigintobj_check (c, args));
}
static void
bigintobj_oozero (bigintobj_c * c, bigintobj_args args)
{
c->hit = 1;
c->val = 0;
c->obj = nil;
assert (bigintobj_check (c, args));
}
static void
bigintobj_copy (bigintobj_c * c, bigintobj_t a, bigintobj_args args)
{
c->hit = a->hit;
c->val = a->val;
c->obj = (a->obj) ? a->obj : nil;
assert (bigintobj_check (c, args) && bigintobj_check (a, args));
}
static void
bigintobj_deepcopy (bigintobj_c * c, bigintobj_t a, bigintobj_args args)
{
c->hit = a->hit;
c->val = a->val;
c->obj = (a->obj) ? [a->obj copy] : nil;
assert (bigintobj_check (c, args) && bigintobj_check (a, args));
}
static void
bigintobj_move (bigintobj_c * c, bigintobj_c * a, bigintobj_args args)
{
assert (bigintobj_check (c, args));
c->hit = a->hit;
c->val = a->val;
a->val = SHRT_MAX;
c->obj = a->obj;
a->obj = nil;
assert (bigintobj_check (c, args));
}
static void
bigintobj_clear (bigintobj_c * c, bigintobj_args args)
{
c->val = SHRT_MAX;
if (c->obj)
c->obj = nil;
}
static bigintobj_args
bigintobj_getargs (id self)
{
bigintobj_args args;
args.proto = self;
return args;
}
static int
bigintobj_size (bigintobj_args args)
{
return 1; /* pointer increment */
}
static int
bigintobj_bsize (bigintobj_args args)
{
return sizeof (bigintobj_c); /* byte size carrier */
}
#if 0
static bigintobj_t
bigintobj_id2t (id object)
{ /* not needed */
}
static bigintobj_c *
bigintobj_id2t (id object)
{ /* not needed */
}
#endif
/*
* initialize scratch space "ref" with a read-only value
*/
static bigintobj_t
bigintobj_id2ref (id object, bigintobj_c * ref)
{
bigintobj_args args = bigintobj_getargs (object); /* use object as proto */
bigintobj_ooobj (ref, object, args);
return ref;
}
/*
* return a new object, containing a copy of "t"
*/
static id
bigintobj_t2id (id proto, bigintobj_t t)
{
bigintobj_args args = bigintobj_getargs (proto);
return bigintobj_obj (t, args);
}
/*
* return a new object, containing "t" itself (moved into object)
*/
static id
bigintobj_c2id (id proto, bigintobj_c * c)
{
id res;
bigintobj_args args = bigintobj_getargs (proto);
res = bigintobj_obj (c, args);
bigintobj_clear (c, args);
return res;
}
static unsigned
bigintobj_hash (bigintobj_t a, bigintobj_args args)
{
return (a->hit) ? a->val : [a->obj hash];
}
static int
bigintobj_iseq (bigintobj_t a, bigintobj_t b, bigintobj_args args)
{
if (a == b)
{
return YES;
}
else
{
if (a->hit)
{
return (b->hit) ? a->val == b->val : NO;
}
else
{
return (b->hit) ? NO : [a->obj isEqual:b->obj];
}
}
}
static int
bigintobj_sgn (bigintobj_t a, bigintobj_args args)
{
if (a->hit)
{
short int sgn = a->val;
return (sgn == 0) ? 0 : ((sgn < 0) ? -1 : +1);
}
else
{
return [a->obj sign];
}
}
static int
bigintobj_cmp (bigintobj_t a, bigintobj_t b, bigintobj_args args)
{
int cmp;
if (a == b)
{
cmp = 0;
}
else
{
if (a->hit && b->hit)
{
cmp = a->val - b->val;
cmp = (cmp == 0) ? 0 : ((cmp < 0) ? -1 : +1);
}
else
{
id A = bigintobj_obj (a, args);
id B = bigintobj_obj (b, args);
cmp = [A compare:B];
}
}
return cmp;
}
static int
bigintobj_iszero (bigintobj_t a, bigintobj_args args)
{
int iszero = (a->hit && a->val == 0);
assert (iszero || (a->hit && a->val != 0) || (a->hit == 0 && [a->obj notZero]));
return iszero;
}
static int
bigintobj_isop (bigintobj_t a, bigintobj_t b, bigintobj_args args)
{
if (a == b)
{
return NO;
}
else
{
if (a->hit)
{
assert (VAL_MAX + VAL_MIN == 0);
assert (VAL_MIN <= a->val && a->val <= VAL_MAX);
assert (VAL_MIN <= b->val && b->val <= VAL_MAX);
return (b->hit) ? a->val + b->val == 0 : NO;
}
else
{
return (b->hit) ? NO : [a->obj isOpposite:b->obj];
}
}
}
static void
bigintobj_ooneg (bigintobj_c * c, bigintobj_t a, bigintobj_args args)
{
if (a->hit)
{
int C = -a->val;
bigintobj_ooval (c, C, args);
}
else
{
bigintobj_ooobj (c, [a->obj negate], args);
}
assert (bigintobj_isop (c, a, args));
}
static void
bigintobj_inneg (bigintobj_c * c, bigintobj_args args)
{
if (c->hit)
{
int C = -c->val;
bigintobj_inval (c, C, args);
}
else
{
bigintobj_inobj (c, [c->obj negate], args);
}
}
static void
bigintobj_oodbl (bigintobj_c * c, bigintobj_t a, int v, bigintobj_args args)
{
if (a->hit)
{
int C = 2 * a->val;
C = (v == +1) ? +C : -C;
bigintobj_ooval (c, C, args);
}
else
{
bigintobj_ooobj (c, [a->obj _double:v], args);
}
}
static void
bigintobj_indbl (bigintobj_c * c, int v, bigintobj_args args)
{
if (c->hit)
{
int C = 2 * c->val;
C = (v == +1) ? +C : -C;
bigintobj_inval (c, C, args);
}
else
{
bigintobj_inobj (c, [c->obj _double:v], args);
}
}
static void
bigintobj_ooadd (bigintobj_c * c, bigintobj_t a, int v, bigintobj_t b, int w, bigintobj_args args)
{
if (a->hit && b->hit)
{
int C = a->val * v + b->val * w;
bigintobj_ooval (c, C, args);
}
else
{
id A, B, C;
A = bigintobj_obj (a, args);
B = bigintobj_obj (b, args);
C = [A _add:v:B:w];
bigintobj_ooobj (c, C, args);
}
}
static void
bigintobj_inadd (bigintobj_c * c, int v, bigintobj_t b, int w, bigintobj_args args)
{
if (c->hit && b->hit)
{
int C = c->val * v + b->val * w;
bigintobj_inval (c, C, args);
}
else
{
id B = bigintobj_obj (b, args);
bigintobj_makeobj (c, args);
bigintobj_inobj (c, [c->obj _add:v:B:w], args);
}
}
static int
bigintobj_isone (bigintobj_t a, bigintobj_args args)
{
return (a->hit && a->val == +1);
}
static int
bigintobj_isminusone (bigintobj_t a, bigintobj_args args)
{
return (a->hit && a->val == -1);
}
static void
bigintobj_oosqr (bigintobj_c * c, bigintobj_t a, bigintobj_args args)
{
if (a->hit)
{
int C = a->val * a->val;
bigintobj_ooval (c, C, args);
}
else
{
bigintobj_ooobj (c, [a->obj square], args);
}
}
static void
bigintobj_insqr (bigintobj_c * c, bigintobj_args args)
{
if (c->hit)
{
int C = c->val * c->val;
bigintobj_inval (c, C, args);
}
else
{
bigintobj_inobj (c, [c->obj square], args);
}
}
static void
bigintobj_oomul (bigintobj_c * c, bigintobj_t a, bigintobj_t b, bigintobj_args args)
{
if (a->hit && b->hit)
{
int C = a->val * b->val;
bigintobj_ooval (c, C, args);
}
else
{
id A, B, C;
A = bigintobj_obj (a, args);
B = bigintobj_obj (b, args);
C = [A multiply:B];
bigintobj_ooobj (c, C, args);
}
}
static void
bigintobj_inmul (bigintobj_c * c, bigintobj_t b, bigintobj_args args)
{
if (c->hit && b->hit)
{
int C = c->val * b->val;
bigintobj_inval (c, C, args);
}
else
{
id B = bigintobj_obj (b, args);
bigintobj_makeobj (c, args);
bigintobj_inobj (c, [c->obj multiply:B], args);
}
}
static void
bigintobj_oomulv (bigintobj_c * c, bigintobj_t a, bigintobj_t b, int v, bigintobj_args args)
{
if (a->hit && b->hit)
{
int C = a->val * b->val * v;
bigintobj_ooval (c, C, args);
}
else
{
id A, B, C;
A = bigintobj_obj (a, args);
B = bigintobj_obj (b, args);
C = [A _multiply:B:v];
bigintobj_ooobj (c, C, args);
}
}
static void
bigintobj_inmulv (bigintobj_c * c, bigintobj_t b, int v, bigintobj_args args)
{
if (c->hit && b->hit)
{
int C = c->val * b->val * v;
bigintobj_inval (c, C, args);
}
else
{
id B = bigintobj_obj (b, args);
bigintobj_makeobj (c, args);
bigintobj_inobj (c, [c->obj _multiply:B:v], args);
}
}
static void
bigintobj_ooaddmul (bigintobj_c * c, bigintobj_t a, int v, bigintobj_t b, bigintobj_t t, int w, bigintobj_args args)
{
if (a->hit && b->hit && t->hit)
{
int C = a->val * v + b->val * t->val * w;
bigintobj_ooval (c, C, args);
}
else
{
id A, B, T, C;
A = bigintobj_obj (a, args);
B = bigintobj_obj (b, args);
T = bigintobj_obj (t, args);
C = [A _add:v:B multiply:T:w];
bigintobj_ooobj (c, C, args);
}
}
static void
bigintobj_inaddmul (bigintobj_c * c, int v, bigintobj_t b, bigintobj_t t, int w, bigintobj_args args)
{
if (c->hit && b->hit && t->hit)
{
int C = c->val * v + b->val * t->val * w;
bigintobj_inval (c, C, args);
}
else
{
id B = bigintobj_obj (b, args);
id T = bigintobj_obj (t, args);
bigintobj_makeobj (c, args);
bigintobj_inobj (c, [c->obj _add:v:B multiply:T:w], args);
}
}
static void
bigintobj_oomuladd (bigintobj_c * c, bigintobj_t a, bigintobj_t s, int v, bigintobj_t b, int w, bigintobj_args args)
{
if (a->hit && s->hit && b->hit)
{
int C = a->val * s->val * v + b->val * w;
bigintobj_ooval (c, C, args);
}
else
{
id A, B, S, C;
A = bigintobj_obj (a, args);
B = bigintobj_obj (b, args);
S = bigintobj_obj (s, args);
C = [A _multiply:S:v add:B:w];
bigintobj_ooobj (c, C, args);
}
}
static void
bigintobj_inmuladd (bigintobj_c * c, bigintobj_t s, int v, bigintobj_t b, int w, bigintobj_args args)
{
if (c->hit && s->hit && b->hit)
{
int C = c->val * s->val * v + b->val * w;
bigintobj_inval (c, C, args);
}
else
{
id B = bigintobj_obj (b, args);
id S = bigintobj_obj (s, args);
bigintobj_makeobj (c, args);
bigintobj_inobj (c, [c->obj _multiply:S:v add:B:w], args);
}
}
static void
bigintobj_oomuladdmul (bigintobj_c * c, bigintobj_t a, bigintobj_t s, int v, bigintobj_t b, bigintobj_t t, int w, bigintobj_args args)
{
if (a->hit && s->hit && b->hit && t->hit)
{
int C = a->val * s->val * v + b->val * t->val * w;
bigintobj_ooval (c, C, args);
}
else
{
id A, B, S, T, C;
A = bigintobj_obj (a, args);
B = bigintobj_obj (b, args);
S = bigintobj_obj (s, args);
T = bigintobj_obj (t, args);
C = [A _multiply:S:v add:B multiply:T:w];
bigintobj_ooobj (c, C, args);
}
}
static void
bigintobj_inmuladdmul (bigintobj_c * c, bigintobj_t s, int v, bigintobj_t b, bigintobj_t t, int w, bigintobj_args args)
{
if (c->hit && s->hit && b->hit && t->hit)
{
int C = c->val * s->val * v + b->val * t->val * w;
bigintobj_inval (c, C, args);
}
else
{
id B = bigintobj_obj (b, args);
id S = bigintobj_obj (s, args);
id T = bigintobj_obj (t, args);
bigintobj_makeobj (c, args);
bigintobj_inobj (c, [c->obj _multiply:S:v add:B multiply:T:w], args);
}
}
static void
bigintobj_ooaddsqr (bigintobj_c * c, bigintobj_t a, int v, bigintobj_t b, int w, bigintobj_args args)
{
if (a->hit && b->hit)
{
int C = a->val * v + b->val * b->val * w;
bigintobj_ooval (c, C, args);
}
else
{
id A, B, C;
A = bigintobj_obj (a, args);
B = bigintobj_obj (b, args);
C = [A _addSquare:v:B:w];
bigintobj_ooobj (c, C, args);
}
}
static void
bigintobj_inaddsqr (bigintobj_c * c, int v, bigintobj_t b, int w, bigintobj_args args)
{
if (c->hit && b->hit)
{
int C = c->val * v + b->val * b->val * w;
bigintobj_inval (c, C, args);
}
else
{
id B = bigintobj_obj (b, args);
bigintobj_makeobj (c, args);
bigintobj_inobj (c, [c->obj _addSquare:v:B:w], args);
}
}
static BOOL
bigintobj_oodiv (bigintobj_c * c, bigintobj_t a, bigintobj_t b, bigintobj_args args)
{
if (a->hit && b->hit)
{
int C;
if (b->val == 0 || a->val % b->val != 0)
{
return FAILURE;
}
else
{
C = a->val / b->val;
}
bigintobj_ooval (c, C, args);
}
else
{
id A, B, C;
A = bigintobj_obj (a, args);
B = bigintobj_obj (b, args);
C = [A divide:B];
if (C == nil)
return FAILURE;
bigintobj_ooobj (c, C, args);
}
return SUCCESS;
}
static void
bigintobj_indiv (bigintobj_c * c, bigintobj_t b, bigintobj_args args)
{
if (c->hit && b->hit)
{
int C;
if (b->val == 0 || c->val % b->val != 0)
{
fprintf (stderr, "-exact division failed\n");
abort ();
}
else
{
C = c->val / b->val;
}
bigintobj_inval (c, C, args);
}
else
{
id C, B = bigintobj_obj (b, args);
bigintobj_makeobj (c, args);
C = [c->obj divide:B];
if (C == nil)
{
fprintf (stderr, "-exact division failed\n");
abort ();
}
bigintobj_inobj (c, C, args);
}
}
static void
bigintobj_args_fileOut (id aFile, bigintobj_args * args)
{
}
static void
bigintobj_args_fileIn (id aFile, bigintobj_args * args)
{
}
static void
bigintobj_fileOut (id aFiler, bigintobj_c * a, bigintobj_args args)
{
assert (bigintobj_check (a, args));
[aFiler fileOut:&a->hit type:'S'];
if (a->hit)
{
[aFiler fileOut:&a->val type:'s']; /* signed ! */
}
else
{
[aFiler fileOut:&a->obj type:'@'];
}
}
static void
bigintobj_fileIn (id aFiler, bigintobj_c * c, bigintobj_args args)
{
[aFiler fileIn:&c->hit type:'S'];
if (c->hit)
{
[aFiler fileIn:&c->val type:'s'];
c->obj = nil;
}
else
{
[aFiler fileIn:&c->obj type:'@'];
}
}
/*
* Computer Algebra Kit (c) 1993,00 by Comp.Alg.Objects. All Rights Reserved.
* $Id: ivectorc.m,v 1.6 2000/10/12 14:40:26 stes Exp $
*/
/*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if bigintobj_pervalue
static bigintobj_t
bigintobjseq_tval (bigintobjseq_t self)
{
return *self;
}
static bigintobj_c *
bigintobjseq_cval (bigintobjseq_t self)
{
return self;
}
#else
static bigintobj_t
bigintobjseq_tval (bigintobjseq_t self)
{
return self;
}
static bigintobj_c *
bigintobjseq_cval (bigintobjseq_t self)
{
return self;
}
#endif
static int
bigintobjseq_check (bigintobjseq_t self, int n, bigintobj_args args)
{
while (n--)
{
bigintobj_check (bigintobjseq_tval (self), args);
self += bigintobj_size (args);
}
return 1;
}
static bigintobjseq_t
bigintobjseq_alloc (int n, bigintobj_args args)
{
bigintobjseq_t p;
int m = n * bigintobj_bsize (args);
#if OBJC_REFCNT
p = (bigintobjseq_t) OC_Calloc (m);
#else
p = (bigintobjseq_t) OC_Malloc (m);
#endif
return p;
}
static bigintobjseq_t
bigintobjseq_realloc (bigintobjseq_t self, int oldc, int n, bigintobj_args args)
{
bigintobjseq_t p;
int m = n * bigintobj_bsize (args);
p = (bigintobjseq_t) OC_Realloc (self, m);
#if OBJC_REFCNT
assert (oldc <= n);
memset (p + oldc, 0, (n - oldc) * bigintobj_bsize (args));
#endif
return p;
}
static bigintobjseq_t
bigintobjseq_free (bigintobjseq_t self, bigintobj_args args)
{
OC_Free (self);
return NULL;
}
static void
bigintobjseq_oozero (bigintobjseq_t c, int n, bigintobj_args args)
{
while (n--)
{
bigintobj_oozero (bigintobjseq_cval (c), args);
c += bigintobj_size (args);
}
}
static void
bigintobjseq_copy (bigintobjseq_t c, bigintobjseq_t a, int n, bigintobj_args args)
{
assert (n >= 0);
while (n--)
{
bigintobj_copy (bigintobjseq_cval (c), bigintobjseq_tval (a), args);
c += bigintobj_size (args);
a += bigintobj_size (args);
}
}
static void
bigintobjseq_deepcopy (bigintobjseq_t c, bigintobjseq_t a, int n, bigintobj_args args)
{
assert (n >= 0);
while (n--)
{
bigintobj_deepcopy (bigintobjseq_cval (c), bigintobjseq_tval (a), args);
c += bigintobj_size (args);
a += bigintobj_size (args);
}
}
#if bigintobj_isvalue
static void
bigintobjseq_clear (bigintobjseq_t self, int n, bigintobj_args args)
{
/* nothing to clear */
}
#else
static void
bigintobjseq_clear (bigintobjseq_t self, int n, bigintobj_args args)
{
while (n--)
{
bigintobj_clear (self, args);
self += bigintobj_size (args);
}
}
#endif /* bigintobj_isvalue */
static int
bigintobjseq_iseq (bigintobjseq_t a, bigintobjseq_t b, int n, bigintobj_args args)
{
assert (n >= 0 && a != b);
while (n--)
{
if (!bigintobj_iseq (bigintobjseq_tval (a), bigintobjseq_tval (b), args))
{
return 0;
}
else
{
a += bigintobj_size (args);
b += bigintobj_size (args);
}
}
return 1;
}
static unsigned
bigintobjseq_hash (bigintobjseq_t a, int n, bigintobj_args args)
{
assert (n >= 0);
return (n) ? bigintobj_hash (bigintobjseq_tval (a), args) : 0;
}
static void
bigintobjseq_place (bigintobjseq_t self, bigintobj_t a, int i, bigintobj_args args)
{
bigintobj_c *c = bigintobjseq_cval (self + i * bigintobj_size (args));
bigintobj_clear (c, args);
bigintobj_copy (c, a, args);
}
static int
bigintobjseq_insertlast (bigintobjseq_t self, bigintobj_t a, int n, bigintobj_args args)
{
bigintobj_c *c;
assert (n >= 0);
c = bigintobjseq_cval (self + n * bigintobj_size (args));
bigintobj_copy (c, a, args);
return ++n;
}
static int
bigintobjseq_insertfirst (bigintobjseq_t self, bigintobj_t a, int n, bigintobj_args args)
{
int j;
assert (n > 0);
self += n * bigintobj_size (args);
j = n;
while (j--)
{
bigintobjseq_t t;
t = self - bigintobj_size (args);
bigintobj_move (bigintobjseq_cval (self), bigintobjseq_cval (t), args);
self = t;
}
bigintobj_copy (bigintobjseq_cval (self), a, args);
return ++n;
}
static int
bigintobjseq_insertat (bigintobjseq_t self, bigintobj_t a, int i, int n, bigintobj_args args)
{
assert (0 <= i && i < n);
self += i * bigintobj_size (args);
return i + bigintobjseq_insertfirst (self, a, n - i, args);
}
static int
bigintobjseq_freelast (bigintobjseq_t self, int n, bigintobj_args args)
{
bigintobj_c *c;
assert (0 < n);
--n;
c = bigintobjseq_cval (self + n * bigintobj_size (args));
bigintobj_clear (c, args);
return n;
}
static int
bigintobjseq_freefirst (bigintobjseq_t self, int n, bigintobj_args args)
{
int j;
assert (0 < n);
bigintobj_clear (bigintobjseq_cval (self), args);
--n;
j = n;
while (j--)
{
bigintobjseq_t t;
t = self + bigintobj_size (args);
bigintobj_move (bigintobjseq_cval (self), bigintobjseq_cval (t), args);
self = t;
}
return n;
}
static int
bigintobjseq_freeat (bigintobjseq_t self, int i, int n, bigintobj_args args)
{
assert (0 <= i && i < n);
self += i * bigintobj_size (args);
return i + bigintobjseq_freefirst (self, n - i, args);
}
static bigintobj_t
bigintobjseq_at (bigintobjseq_t self, int i, bigintobj_args args)
{
bigintobj_t res;
assert (0 <= i);
res = bigintobjseq_tval (self + i * bigintobj_size (args));
assert (bigintobj_check (res, args));
return res;
}
static bigintobj_t
bigintobjseq_last (bigintobjseq_t self, int n, bigintobj_args args)
{
return bigintobjseq_at (self, n - 1, args);
}
static bigintobj_c *
bigintobjseq_cvalat (bigintobjseq_t self, int i, bigintobj_args args)
{
assert (0 <= i);
return bigintobjseq_cval (self + i * bigintobj_size (args));
}
static int
bigintobjseq_iszero (bigintobjseq_t a, int n, bigintobj_args args)
{
assert (n >= 0);
while (n--)
{
if (bigintobj_iszero (bigintobjseq_tval (a), args))
{
a += bigintobj_size (args);
}
else
{
return 0;
}
}
return 1;
}
static int
bigintobjseq_isop (bigintobjseq_t a, bigintobjseq_t b, int n, bigintobj_args args)
{
assert (n >= 0 && a != b);
while (n--)
{
if (!bigintobj_isop (bigintobjseq_tval (a), bigintobjseq_tval (b), args))
{
return 0;
}
else
{
a += bigintobj_size (args);
b += bigintobj_size (args);
}
}
return 1;
}
static void
bigintobjseq_ooneg (bigintobjseq_t c, bigintobjseq_t a, int n, bigintobj_args args)
{
assert (n >= 0);
while (n--)
{
bigintobj_ooneg (bigintobjseq_cval (c), bigintobjseq_tval (a), args);
c += bigintobj_size (args);
a += bigintobj_size (args);
}
}
static void
bigintobjseq_inneg (bigintobjseq_t a, int n, bigintobj_args args)
{
assert (n >= 0);
while (n--)
{
bigintobj_inneg (bigintobjseq_cval (a), args);
a += bigintobj_size (args);
}
}
static void
bigintobjseq_oonegv (bigintobjseq_t c, bigintobjseq_t a, int v, int n, bigintobj_args args)
{
assert (v * v == 1);
if (v == -1)
bigintobjseq_ooneg (c, a, n, args);
else
bigintobjseq_copy (c, a, n, args);
}
static void
bigintobjseq_innegv (bigintobjseq_t a, int v, int n, bigintobj_args args)
{
assert (v * v == 1);
if (v == -1)
bigintobjseq_inneg (a, n, args);
}
static void
bigintobjseq_oodbl (bigintobjseq_t c, bigintobjseq_t a, int v, int n, bigintobj_args args)
{
assert (n >= 0 && v * v == 1);
while (n--)
{
bigintobj_oodbl (bigintobjseq_cval (c), bigintobjseq_tval (a), v, args);
c += bigintobj_size (args);
a += bigintobj_size (args);
}
}
static void
bigintobjseq_indbl (bigintobjseq_t a, int v, int n, bigintobj_args args)
{
assert (n >= 0 && v * v == 1);
while (n--)
{
bigintobj_indbl (bigintobjseq_cval (a), v, args);
a += bigintobj_size (args);
}
}
static void
bigintobjseq_ooadd (bigintobjseq_t c, bigintobjseq_t a, int v, bigintobjseq_t b, int w, int n, bigintobj_args args)
{
assert (n >= 0 && a != b && v * v == 1 && w * w == 1);
while (n--)
{
bigintobj_ooadd (bigintobjseq_cval (c), bigintobjseq_tval (a), v, bigintobjseq_tval (b), w, args);
c += bigintobj_size (args);
a += bigintobj_size (args);
b += bigintobj_size (args);
}
}
static void
bigintobjseq_inadd (bigintobjseq_t a, int v, bigintobjseq_t b, int w, int n, bigintobj_args args)
{
assert (n >= 0 && a != b && v * v == 1 && w * w == 1);
while (n--)
{
bigintobj_inadd (bigintobjseq_cval (a), v, bigintobjseq_tval (b), w, args);
a += bigintobj_size (args);
b += bigintobj_size (args);
}
}
static void
bigintobjseq_oomulsc (bigintobjseq_t c, bigintobjseq_t a, bigintobj_t s, int n, bigintobj_args args)
{
assert (n >= 0);
while (n--)
{
bigintobj_oomul (bigintobjseq_cval (c), bigintobjseq_tval (a), s, args);
c += bigintobj_size (args);
a += bigintobj_size (args);
}
}
static void
bigintobjseq_inmulsc (bigintobjseq_t a, bigintobj_t s, int n, bigintobj_args args)
{
assert (n >= 0);
while (n--)
{
bigintobj_inmul (bigintobjseq_cval (a), s, args);
a += bigintobj_size (args);
}
}
static void
bigintobjseq_oomulscv (bigintobjseq_t c, bigintobjseq_t a, bigintobj_t s, int v, int n, bigintobj_args args)
{
assert (n >= 0 && v * v == 1);
while (n--)
{
bigintobj_oomulv (bigintobjseq_cval (c), bigintobjseq_tval (a), s, v, args);
c += bigintobj_size (args);
a += bigintobj_size (args);
}
}
static void
bigintobjseq_inmulscv (bigintobjseq_t a, bigintobj_t s, int v, int n, bigintobj_args args)
{
assert (n >= 0 && v * v == 1);
while (n--)
{
bigintobj_inmulv (bigintobjseq_cval (a), s, v, args);
a += bigintobj_size (args);
}
}
static void
bigintobjseq_ooaddmulsc (bigintobjseq_t c, bigintobjseq_t a, int v, bigintobjseq_t b, bigintobj_t t, int w, int n, bigintobj_args args)
{
assert (n >= 0 && v * v == 1 && w * w == 1);
while (n--)
{
bigintobj_ooaddmul (bigintobjseq_cval (c), bigintobjseq_tval (a), v, bigintobjseq_tval (b), t, w, args);
a += bigintobj_size (args);
b += bigintobj_size (args);
c += bigintobj_size (args);
}
}
static void
bigintobjseq_oomulscadd (bigintobjseq_t c, bigintobjseq_t a, bigintobj_t s, int v, bigintobjseq_t b, int w, int n, bigintobj_args args)
{
assert (n >= 0 && v * v == 1 && w * w == 1);
while (n--)
{
bigintobj_oomuladd (bigintobjseq_cval (c), bigintobjseq_tval (a), s, v, bigintobjseq_tval (b), w, args);
a += bigintobj_size (args);
b += bigintobj_size (args);
c += bigintobj_size (args);
}
}
static void
bigintobjseq_oomulscaddmulsc (bigintobjseq_t c, bigintobjseq_t a, bigintobj_t s, int v, bigintobjseq_t b, bigintobj_t t, int w, int n, bigintobj_args args)
{
assert (n >= 0 && v * v == 1 && w * w == 1);
while (n--)
{
bigintobj_oomuladdmul (bigintobjseq_cval (c), bigintobjseq_tval (a), s, v, bigintobjseq_tval (b), t, w, args);
a += bigintobj_size (args);
b += bigintobj_size (args);
c += bigintobj_size (args);
}
}
static void
bigintobjseq_inaddmulsc (bigintobjseq_t a, int v, bigintobjseq_t b, bigintobj_t t, int w, int n, bigintobj_args args)
{
assert (n >= 0 && v * v == 1 && w * w == 1);
while (n--)
{
bigintobj_inaddmul (bigintobjseq_cval (a), v, bigintobjseq_tval (b), t, w, args);
a += bigintobj_size (args);
b += bigintobj_size (args);
}
}
static void
bigintobjseq_inmulscadd (bigintobjseq_t a, bigintobj_t s, int v, bigintobjseq_t b, int w, int n, bigintobj_args args)
{
assert (n >= 0 && v * v == 1 && w * w == 1);
while (n--)
{
bigintobj_inmuladd (bigintobjseq_cval (a), s, v, bigintobjseq_tval (b), w, args);
a += bigintobj_size (args);
b += bigintobj_size (args);
}
}
static void
bigintobjseq_inmulscaddmulsc (bigintobjseq_t a, bigintobj_t s, int v, bigintobjseq_t b, bigintobj_t t, int w, int n, bigintobj_args args)
{
assert (n >= 0 && v * v == 1 && w * w == 1);
while (n--)
{
bigintobj_inmuladdmul (bigintobjseq_cval (a), s, v, bigintobjseq_tval (b), t, w, args);
a += bigintobj_size (args);
b += bigintobj_size (args);
}
}
static BOOL
bigintobjseq_oodivsc (bigintobjseq_t c, bigintobjseq_t a, bigintobj_t s, int n, bigintobj_args args)
{
int i;
BOOL failed;
bigintobjseq_t orgc = c;
assert (n >= 0);
for (i = 0; i < n; i++)
{
failed = bigintobj_oodiv (bigintobjseq_cval (c), bigintobjseq_tval (a), s, args);
if (failed)
{
bigintobjseq_clear (orgc, i - 1, args);
return FAILURE;
}
else
{
c += bigintobj_size (args);
a += bigintobj_size (args);
}
}
return SUCCESS;
}
static void
bigintobjseq_indivsc (bigintobjseq_t a, bigintobj_t s, int n, bigintobj_args args)
{
assert (n >= 0);
while (n--)
{
bigintobj_indiv (bigintobjseq_cval (a), s, args);
a += bigintobj_size (args);
}
}
static void
bigintobjseq_oodotsqr (bigintobj_c * c, bigintobjseq_t a, int n, bigintobj_args args)
{
assert (n >= 0);
bigintobj_oozero (c, args);
while (n--)
{
bigintobj_inaddsqr (c, +1, bigintobjseq_tval (a), +1, args);
a += bigintobj_size (args);
}
}
static void
bigintobjseq_oodotmul (bigintobj_c * c, bigintobjseq_t a, bigintobjseq_t b, int n, bigintobj_args args)
{
assert (n >= 0);
bigintobj_oozero (c, args);
while (n--)
{
bigintobj_inaddmul (c, +1, bigintobjseq_tval (a), bigintobjseq_tval (b), +1, args);
a += bigintobj_size (args);
b += bigintobj_size (args);
}
}
static void
bigintobjseq_args_fileOut (id aFiler, bigintobj_args * args)
{
bigintobj_args_fileOut (aFiler, args);
}
static void
bigintobjseq_args_fileIn (id aFiler, bigintobj_args * args)
{
bigintobj_args_fileIn (aFiler, args);
}
static void
bigintobjseq_fileOut (id aFiler, bigintobjseq_t self, int n, bigintobj_args args)
{
assert (n >= 0);
while (n--)
{
bigintobj_fileOut (aFiler, bigintobjseq_cval (self), args);
self += bigintobj_size (args);
}
}
static void
bigintobjseq_fileIn (id aFiler, bigintobjseq_t self, int n, bigintobj_args args)
{
assert (n >= 0);
while (n--)
{
bigintobj_fileIn (aFiler, bigintobjseq_cval (self), args);
self += bigintobj_size (args);
}
}
static bigintobjvec_args
bigintobjvec_getargs (id self)
{
bigintobjvec_args args;
args.sargs = bigintobj_getargs ([self scalarZero]);
return args;
}
static int
bigintobjvec_check (bigintobjvec_t self, bigintobjvec_args args)
{
assert (0 <= self->n && self->n <= self->c);
bigintobjseq_check (self->ptr, self->n, args.sargs);
return 1;
}
static bigintobjvec_t
bigintobjvec_id2t (id object)
{
return [object bigintobjvec_value];
}
static bigintobjvec_c *
bigintobjvec_id2c (id object)
{
return [object bigintobjvec_reference];
}
static id
bigintobjvec_t2id (id proto, bigintobjvec_t f)
{
return [proto bigintobjvec_value:f];
}
static id
bigintobjvec_c2id (id proto, bigintobjvec_c * r)
{
return [proto bigintobjvec_reference:r];
}
static void
bigintobjvec_init (bigintobjvec_t self, int n, bigintobjvec_args args)
{
self->n = n;
self->c = n;
self->ptr = bigintobjseq_alloc (n, args.sargs);
}
static void
bigintobjvec_initcount (bigintobjvec_t c, int n, bigintobjvec_args args)
{
bigintobjvec_init (c, n, args);
bigintobjseq_oozero (c->ptr, n, args.sargs);
}
static void
bigintobjvec_initcapacity (bigintobjvec_t self, int n, bigintobjvec_args args)
{
self->n = 0;
self->c = n;
self->ptr = bigintobjseq_alloc (n, args.sargs);
}
static void
bigintobjvec_copy (bigintobjvec_t c, bigintobjvec_t a, bigintobjvec_args args)
{
bigintobjvec_init (c, a->n, args);
bigintobjseq_copy (c->ptr, a->ptr, a->n, args.sargs);
}
static void
bigintobjvec_deepcopy (bigintobjvec_t c, bigintobjvec_t a, bigintobjvec_args args)
{
bigintobjvec_init (c, a->n, args);
bigintobjseq_deepcopy (c->ptr, a->ptr, a->n, args.sargs);
}
static void
bigintobjvec_move (bigintobjvec_t c, bigintobjvec_t a, bigintobjvec_args args)
{
c->n = a->n;
c->c = a->c;
c->ptr = a->ptr;
a->ptr = NULL;
}
static void
bigintobjvec_destroy (bigintobjvec_t self, bigintobjvec_args args)
{
/*
* clearing memory allocated by bigintobjvec_init after a failed operation
* can't do a bigintobjseq_clear in that case as the handler doesnt know
* what elements have been allocated
*/
self->ptr = bigintobjseq_free (self->ptr, args.sargs);
}
static void
bigintobjvec_clear (bigintobjvec_t self, bigintobjvec_args args)
{
bigintobjseq_clear (self->ptr, self->n, args.sargs);
bigintobjvec_destroy (self, args);
}
static int
bigintobjvec_count (bigintobjvec_t self)
{
return self->n;
}
static unsigned
bigintobjvec_hash (bigintobjvec_t a, bigintobjvec_args args)
{
return bigintobjseq_hash (a->ptr, a->n, args.sargs);
}
static int
bigintobjvec_iseq (bigintobjvec_t a, bigintobjvec_t b, bigintobjvec_args args)
{
assert (a != b);
return (a->n == b->n && bigintobjseq_iseq (a->ptr, b->ptr, a->n, args.sargs));
}
static void
bigintobjvec_expand (bigintobjvec_t self, bigintobjvec_args args)
{
int oldc = self->c;
assert (self->n == self->c);
self->c = self->n + self->c + 1;
self->ptr = bigintobjseq_realloc (self->ptr, oldc, self->c, args.sargs);
assert (self->n < self->c);
}
static void
bigintobjvec_insertfirst (bigintobjvec_t self, bigintobj_t a, bigintobjvec_args args)
{
assert (self->n <= self->c);
if (self->n == self->c)
bigintobjvec_expand (self, args);
self->n = bigintobjseq_insertlast (self->ptr, a, self->n, args.sargs);
}
static void
bigintobjvec_insertat (bigintobjvec_t self, bigintobj_t a, int i, bigintobjvec_args args)
{
assert (0 < i && i <= self->n && self->n <= self->c);
if (self->n == self->c)
bigintobjvec_expand (self, args);
if (i == self->n)
{
self->n = bigintobjseq_insertfirst (self->ptr, a, self->n, args.sargs);
}
else
{
self->n = bigintobjseq_insertat (self->ptr, a, self->n - i - 1, self->n, args.sargs);
}
}
static void
bigintobjvec_place (bigintobjvec_t self, bigintobj_t a, int i, bigintobjvec_args args)
{
assert (0 <= i && i < self->n);
bigintobjseq_place (self->ptr, a, self->n - i - 1, args.sargs);
}
static void
bigintobjvec_freefirst (bigintobjvec_t self, bigintobjvec_args args)
{
assert (self->n > 0);
self->n = bigintobjseq_freelast (self->ptr, self->n, args.sargs);
}
static void
bigintobjvec_freeat (bigintobjvec_t self, int i, bigintobjvec_args args)
{
assert (0 < i && i < self->n);
self->n = bigintobjseq_freeat (self->ptr, self->n - i - 1, self->n, args.sargs);
}
static bigintobj_t
bigintobjvec_at (bigintobjvec_t self, int ix, bigintobjvec_args args)
{
assert (0 <= ix && ix < self->n);
return bigintobjseq_at (self->ptr, self->n - ix - 1, args.sargs);
}
static bigintobj_t
bigintobjvec_first (bigintobjvec_t self, bigintobjvec_args args)
{
assert (self->n > 0);
return bigintobjseq_last (self->ptr, self->n, args.sargs);
}
static bigintobj_t
bigintobjvec_elt (bigintobjvec_t self, bigintobjvec_ixt ix, bigintobjvec_args args)
{
assert (ix->n == self->n);
return bigintobjvec_at (self, ix->i, args);
}
static int
bigintobjvec_iszero (bigintobjvec_t self, bigintobjvec_args args)
{
return bigintobjseq_iszero (self->ptr, self->n, args.sargs);
}
static int
bigintobjvec_isop (bigintobjvec_t a, bigintobjvec_t b, bigintobjvec_args args)
{
assert (a != b);
return (a->n == b->n && bigintobjseq_isop (a->ptr, b->ptr, a->n, args.sargs));
}
static void
bigintobjvec_ooneg (bigintobjvec_t c, bigintobjvec_t a, bigintobjvec_args args)
{
bigintobjvec_init (c, a->n, args);
bigintobjseq_ooneg (c->ptr, a->ptr, a->n, args.sargs);
}
static void
bigintobjvec_inneg (bigintobjvec_t a, bigintobjvec_args args)
{
bigintobjseq_inneg (a->ptr, a->n, args.sargs);
}
static void
bigintobjvec_oodbl (bigintobjvec_t c, bigintobjvec_t a, int v, bigintobjvec_args args)
{
bigintobjvec_init (c, a->n, args);
bigintobjseq_oodbl (c->ptr, a->ptr, v, a->n, args.sargs);
}
static void
bigintobjvec_indbl (bigintobjvec_t a, int v, bigintobjvec_args args)
{
bigintobjseq_indbl (a->ptr, v, a->n, args.sargs);
}
static void
bigintobjvec_checkcount (int a, int b)
{
if (a != b)
{
fprintf (stderr, "Vector : Dimensions Not Equal\n");
abort ();
}
}
static void
bigintobjvec_ooadd (bigintobjvec_t c, bigintobjvec_t a, int v, bigintobjvec_t b, int w, bigintobjvec_args args)
{
assert (a != b);
bigintobjvec_checkcount (a->n, b->n);
bigintobjvec_init (c, a->n, args);
bigintobjseq_ooadd (c->ptr, a->ptr, v, b->ptr, w, a->n, args.sargs);
}
static void
bigintobjvec_inadd (bigintobjvec_t a, int v, bigintobjvec_t b, int w, bigintobjvec_args args)
{
assert (a != b);
bigintobjvec_checkcount (a->n, b->n);
bigintobjseq_inadd (a->ptr, v, b->ptr, w, a->n, args.sargs);
}
static void
bigintobjvec_oomulsc (bigintobjvec_t c, bigintobjvec_t a, bigintobj_t s, bigintobjvec_args args)
{
bigintobjvec_init (c, a->n, args);
bigintobjseq_oomulsc (c->ptr, a->ptr, s, a->n, args.sargs);
}
static void
bigintobjvec_inmulsc (bigintobjvec_t a, bigintobj_t s, bigintobjvec_args args)
{
bigintobjseq_inmulsc (a->ptr, s, a->n, args.sargs);
}
static void
bigintobjvec_ooaddmulsc (bigintobjvec_t c, bigintobjvec_t a, int v, bigintobjvec_t b, bigintobj_t s, int w, bigintobjvec_args args)
{
assert (a != b);
bigintobjvec_checkcount (a->n, b->n);
bigintobjvec_init (c, a->n, args);
bigintobjseq_ooaddmulsc (c->ptr, a->ptr, v, b->ptr, s, w, a->n, args.sargs);
}
static void
bigintobjvec_inaddmulsc (bigintobjvec_t a, int v, bigintobjvec_t b, bigintobj_t s, int w, bigintobjvec_args args)
{
assert (a != b);
bigintobjvec_checkcount (a->n, b->n);
bigintobjseq_inaddmulsc (a->ptr, v, b->ptr, s, w, a->n, args.sargs);
}
static void
bigintobjvec_oomulscadd (bigintobjvec_t c, bigintobjvec_t a, bigintobj_t s, int v, bigintobjvec_t b, int w, bigintobjvec_args args)
{
assert (a != b);
bigintobjvec_checkcount (a->n, b->n);
bigintobjvec_init (c, a->n, args);
bigintobjseq_oomulscadd (c->ptr, a->ptr, s, v, b->ptr, w, a->n, args.sargs);
}
static void
bigintobjvec_inmulscadd (bigintobjvec_t a, bigintobj_t s, int v, bigintobjvec_t b, int w, bigintobjvec_args args)
{
assert (a != b);
bigintobjvec_checkcount (a->n, b->n);
bigintobjseq_inmulscadd (a->ptr, s, v, b->ptr, w, a->n, args.sargs);
}
static void
bigintobjvec_oomulscaddmulsc (bigintobjvec_t c, bigintobjvec_t a, bigintobj_t s, int v, bigintobjvec_t b, bigintobj_t t, int w, bigintobjvec_args args)
{
assert (a != b);
bigintobjvec_checkcount (a->n, b->n);
bigintobjvec_init (c, a->n, args);
bigintobjseq_oomulscaddmulsc (c->ptr, a->ptr, s, v, b->ptr, t, w, a->n, args.sargs);
}
static void
bigintobjvec_inmulscaddmulsc (bigintobjvec_t a, bigintobj_t s, int v, bigintobjvec_t b, bigintobj_t t, int w, bigintobjvec_args args)
{
assert (a != b);
bigintobjvec_checkcount (a->n, b->n);
bigintobjseq_inmulscaddmulsc (a->ptr, s, v, b->ptr, t, w, a->n, args.sargs);
}
static BOOL
bigintobjvec_oodivsc (bigintobjvec_t c, bigintobjvec_t a, bigintobj_t s, bigintobjvec_args args)
{
BOOL failed;
bigintobjvec_init (c, a->n, args);
failed = bigintobjseq_oodivsc (c->ptr, a->ptr, s, a->n, args.sargs);
if (failed)
bigintobjvec_destroy (c, args);
return failed;
}
static void
bigintobjvec_indivsc (bigintobjvec_t a, bigintobj_t s, bigintobjvec_args args)
{
bigintobjseq_indivsc (a->ptr, s, a->n, args.sargs);
}
static void
bigintobjvec_oodotmul (bigintobj_c * c, bigintobjvec_t a, bigintobjvec_t b, bigintobjvec_args args)
{
assert (a != b);
bigintobjvec_checkcount (a->n, b->n);
bigintobjseq_oodotmul (c, a->ptr, b->ptr, a->n, args.sargs);
}
static void
bigintobjvec_oodotsqr (bigintobj_c * c, bigintobjvec_t a, bigintobjvec_args args)
{
bigintobjseq_oodotsqr (c, a->ptr, a->n, args.sargs);
}
static void
bigintobjvec_args_fileOut (id aFiler, bigintobjvec_args * args)
{
bigintobjseq_args_fileOut (aFiler, &args->sargs);
}
static void
bigintobjvec_args_fileIn (id aFiler, bigintobjvec_args * args)
{
bigintobjseq_args_fileIn (aFiler, &args->sargs);
}
static void
bigintobjvec_fileOut (id aFiler, bigintobjvec_t self, bigintobjvec_args args)
{
[aFiler fileOut:&self->n type:'i'];
bigintobjseq_fileOut (aFiler, self->ptr, self->n, args.sargs);
}
static void
bigintobjvec_fileIn (id aFiler, bigintobjvec_t self, bigintobjvec_args args)
{
int n;
[aFiler fileIn:&n type:'i'];
bigintobjvec_init (self, n, args);
bigintobjseq_fileIn (aFiler, self->ptr, self->n, args.sargs);
}
static void
bigintobjvec_ix_init (bigintobjvec_ixt ix, id self)
{
bigintobjvec_t v = [self bigintobjvec_value];
ix->n = v->n;
}
static void
bigintobjvec_ix_copy (bigintobjvec_ixt c, bigintobjvec_ixt a)
{
c->i = a->i;
c->n = a->n;
}
static void
bigintobjvec_ix_clear (bigintobjvec_ixt ix)
{
/* nothing to clear */
}
static int
bigintobjvec_ix_count (bigintobjvec_ixt ix)
{
return ix->n;
}
static int
bigintobjvec_ix_isempty (bigintobjvec_ixt ix)
{
return ix->n == 0;
}
static int
bigintobjvec_ix_ismatch (bigintobjvec_ixt ix)
{
assert (-1 <= ix->i && ix->i <= ix->n);
return 0 <= ix->i && ix->i < ix->n;
}
static void
bigintobjvec_ix_tofirst (bigintobjvec_ixt ix)
{
ix->i = -1; /* next -> first */
}
static void
bigintobjvec_ix_tolast (bigintobjvec_ixt ix)
{
ix->i = ix->n; /* prev -> last */
}
static void
bigintobjvec_ix_to (bigintobjvec_ixt ix, int i)
{
/* the actual position is n-i-1; conversion done in elting routine... */
if (i < 0)
ix->i = -1;
else if (i > ix->n)
ix->i = ix->n;
else
ix->i = i - 1; /* next -> at i */
}
static void
bigintobjvec_ix_next (bigintobjvec_ixt ix)
{
ix->i = (ix->i < ix->n) ? ix->i + 1 : ix->n;
}
static void
bigintobjvec_ix_prev (bigintobjvec_ixt ix)
{
ix->i = (0 <= ix->i) ? ix->i - 1 : -1;
}
@implementation bigintobj_vector : vectorc
- check
{
[super check];
[scalarZero check];
bigintobjvec_check (&value, bigintobjvec_getargs (self));
return self;
}
- _setUpScalarZero:aScalarZero numScalars:(int)numScalars
{
scalarZero = aScalarZero;
bigintobjvec_initcount (&value, numScalars, bigintobjvec_getargs (self));
assert ([self check]);
return self;
}
+ scalarZero:aScalarZero numScalars:(int)numScalars
{
return [[super new] _setUpScalarZero:aScalarZero numScalars:numScalars];
}
- copy
{
bigintobjvec_c c;
assert ([self check]);
bigintobjvec_copy (&c, &value, bigintobjvec_getargs (self));
return bigintobjvec_c2id (self, &c);
}
- deepCopy
{
bigintobjvec_c c;
assert ([self check]);
bigintobjvec_deepcopy (&c, &value, bigintobjvec_getargs (self));
return bigintobjvec_c2id (self, &c);
}
- release
{
bigintobjvec_clear (&value, bigintobjvec_getargs (self));
return [super release];
}
- (bigintobjvec_t)bigintobjvec_value
{
return &value;
}
- dobigintobjvec_value:(bigintobjvec_t)aValue
{
bigintobjvec_copy (&value, aValue, bigintobjvec_getargs (self));
assert ([self check]);
return self;
}
- bigintobjvec_value:(bigintobjvec_t)aValue
{
return [[self clone] dobigintobjvec_value:aValue];
}
- (bigintobjvec_t)bigintobjvec_reference
{
return &value;
}
- dobigintobjvec_reference:(bigintobjvec_c *)aReference
{
bigintobjvec_move (&value, aReference, bigintobjvec_getargs (self));
assert ([self check]);
return self;
}
- bigintobjvec_reference:(bigintobjvec_c *)aReference
{
return [[self clone] dobigintobjvec_reference:aReference];
}
- capacity:(int)aCapacity
{
bigintobjvec_c c;
assert ([self check]);
bigintobjvec_initcapacity (&c, aCapacity, bigintobjvec_getargs (self));
return bigintobjvec_c2id (self, &c);
}
- numScalars:(int)numScalars
{
bigintobjvec_c c;
assert ([self check]);
bigintobjvec_initcount (&c, numScalars, bigintobjvec_getargs (self));
return bigintobjvec_c2id (self, &c);
}
- scalarZero
{
return scalarZero;
}
- (int) numScalars
{
assert ([self check]);
return bigintobjvec_count (&value);
}
- insertScalar:aScalar
{
bigintobj_c c;
assert ([aScalar check]);
assert ([self check]);
bigintobjvec_insertfirst (&value, bigintobj_id2ref (aScalar, &c), bigintobjvec_getargs (self));
assert ([aScalar check]);
assert ([self check]);
[self invalidate];
return self;
}
- insertScalar:aScalar at:(int)i
{
bigintobj_c c;
assert (aScalar);
assert ([self check]);
bigintobjvec_insertat (&value, bigintobj_id2ref (aScalar, &c), i, bigintobjvec_getargs (self));
assert ([aScalar check]);
assert ([self check]);
[self invalidate];
return self;
}
- removeScalar
{
if ([self numScalars])
{
id res;
bigintobj_t t = bigintobjvec_first (&value, bigintobjvec_getargs (self));
assert ([self check]);
res = bigintobj_t2id (scalarZero, t);
bigintobjvec_freefirst (&value, bigintobjvec_getargs (self));
assert ([self check]);
assert ([res check]);
[self invalidate];
return res;
}
else
{
return nil;
}
}
- removeScalarAt:(int)i
{
id res;
assert ([self check]);
res = bigintobj_t2id (scalarZero, bigintobjvec_at (&value, i, bigintobjvec_getargs (self)));
bigintobjvec_freeat (&value, i, bigintobjvec_getargs (self));
assert ([self check]);
assert ([res check]);
[self invalidate];
return res;
}
- placeScalar:aScalar at:(int)i
{
bigintobj_c c;
assert ([aScalar check]);
assert ([self check]);
bigintobjvec_place (&value, bigintobj_id2ref (aScalar, &c), i, bigintobjvec_getargs (self));
assert ([aScalar check]);
assert ([self check]);
[self invalidate];
return self;
}
- replaceScalarAt:(int)i with:aScalar
{
id res;
bigintobj_c c;
bigintobj_t t = bigintobjvec_at (&value, i, bigintobjvec_getargs (self));
assert ([self check]);
res = bigintobj_t2id (scalarZero, t);
bigintobjvec_place (&value, bigintobj_id2ref (aScalar, &c), i, bigintobjvec_getargs (self));
assert ([aScalar check]);
assert ([self check]);
assert ([res check]);
[self invalidate];
return res;
}
- eachScalar
{
id aSequence = [bigintobjvec_sequence content:self];
return [CASequence over:aSequence];
}
- elt_bigintobjvec_ix:(bigintobjvec_ixt)ix
{
if (bigintobjvec_ix_ismatch (ix))
{
bigintobj_t t = bigintobjvec_elt (&value, ix, bigintobjvec_getargs (self));
return bigintobj_t2id (scalarZero, t);
}
else
{
return nil;
}
}
- dotMultiply:b
{
bigintobj_c c; /* carrier for scalar */
bigintobjvec_oodotmul (&c, &value, [b bigintobjvec_value], bigintobjvec_getargs (self));
/* now promote the carrier to object */
/* all of this used to be very difficult in 0.6 */
return bigintobj_c2id (scalarZero, &c);
}
- dotSquare
{
bigintobj_c c; /* carrier for scalar */
bigintobjvec_oodotsqr (&c, &value, bigintobjvec_getargs (self));
/* now promote the carrier to object */
/* all of this used to be very difficult in 0.6 */
return bigintobj_c2id (scalarZero, &c);
}
- fileOutOn:aFiler
{
bigintobjvec_args args;
assert ([self check]);
[super fileOutOn:aFiler];
args = bigintobjvec_getargs (self);
bigintobjvec_args_fileOut (aFiler, &args);
bigintobjvec_fileOut (aFiler, &value, args);
return self;
}
- fileInFrom:aFiler
{
bigintobjvec_args args;
[super fileInFrom:aFiler];
bigintobjvec_args_fileIn (aFiler, &args);
bigintobjvec_fileIn (aFiler, &value, args);
return self;
}
- (unsigned) hash
{
return bigintobjvec_hash (bigintobjvec_id2t (self), bigintobjvec_getargs (self));
}
- (BOOL) isEqual:b
{
[self checkSameClass:b];
if (self == b)
{
return YES;
}
else
{
return bigintobjvec_iseq (bigintobjvec_id2t (self), bigintobjvec_id2t (b), bigintobjvec_getargs (self));
}
}
- (BOOL) notEqual:b
{
[self checkSameClass:b];
if (self == b)
{
return NO;
}
else
{
return !bigintobjvec_iseq (bigintobjvec_id2t (self), bigintobjvec_id2t (b), bigintobjvec_getargs (self));
}
}
- (BOOL) isZero
{
assert ([self check]);
return bigintobjvec_iszero (bigintobjvec_id2t (self), bigintobjvec_getargs (self));
}
- (BOOL) notZero
{
assert ([self check]);
return !bigintobjvec_iszero (bigintobjvec_id2t (self), bigintobjvec_getargs (self));
}
- (BOOL) isOpposite:b
{
assert ([self checkSameClass:b] && self != b);
return bigintobjvec_isop (bigintobjvec_id2t (self), bigintobjvec_id2t (b), bigintobjvec_getargs (self));
}
- (BOOL) notOpposite:b
{
assert ([self checkSameClass:b] && self != b);
return !bigintobjvec_isop (bigintobjvec_id2t (self), bigintobjvec_id2t (b), bigintobjvec_getargs (self));
}
- negate
{
bigintobjvec_c c;
assert ([self check]);
bigintobjvec_ooneg (&c, bigintobjvec_id2t (self), bigintobjvec_getargs (self));
return bigintobjvec_c2id (self, &c);
}
- _double:(int)v
{
bigintobjvec_c c;
assert ([self check]);
bigintobjvec_oodbl (&c, bigintobjvec_id2t (self), v, bigintobjvec_getargs (self));
return bigintobjvec_c2id (self, &c);
}
- double
{
bigintobjvec_c c;
assert ([self check]);
bigintobjvec_oodbl (&c, bigintobjvec_id2t (self), +1, bigintobjvec_getargs (self));
return bigintobjvec_c2id (self, &c);
}
- _add:(int)v:b:(int)w
{
bigintobjvec_c c;
assert ([self sameClass:b] && v * v == 1 && w * w == 1 && self != b);
bigintobjvec_ooadd (&c, bigintobjvec_id2t (self), v, bigintobjvec_id2t (b), w, bigintobjvec_getargs (self));
return bigintobjvec_c2id (self, &c);
}
- add:b
{
bigintobjvec_c c;
assert ([self checkSameClass:b] && self != b);
bigintobjvec_ooadd (&c, bigintobjvec_id2t (self), +1, bigintobjvec_id2t (b), +1, bigintobjvec_getargs (self));
return bigintobjvec_c2id (self, &c);
}
- subtract:b
{
bigintobjvec_c c;
assert ([self checkSameClass:b] && self != b);
bigintobjvec_ooadd (&c, bigintobjvec_id2t (self), +1, bigintobjvec_id2t (b), -1, bigintobjvec_getargs (self));
return bigintobjvec_c2id (self, &c);
}
- multiplyScalar:s
{
bigintobjvec_c c;
bigintobj_c sc;
bigintobjvec_oomulsc (&c, bigintobjvec_id2t (self), bigintobj_id2ref (s, &sc), bigintobjvec_getargs (self));
return bigintobjvec_c2id (self, &c);
}
- divideScalar:s
{
bigintobjvec_c c;
bigintobj_c sc;
BOOL failed = bigintobjvec_oodivsc (&c, bigintobjvec_id2t (self), bigintobj_id2ref (s, &sc), bigintobjvec_getargs (self));
return (failed) ? nil : bigintobjvec_c2id (self, &c);
}
- _add:(int)v:B multiplyScalar:b:(int)w
{
bigintobjvec_c c;
bigintobj_c bc;
assert ([self sameClass:B] && [scalarZero sameClass:b] && v * v == 1 && w * w == 1);
bigintobjvec_ooaddmulsc (&c, bigintobjvec_id2t (self), v, bigintobjvec_id2t (B), bigintobj_id2ref (b, &bc), w, bigintobjvec_getargs (self));
return bigintobjvec_c2id (self, &c);
}
- _multiplyScalar:a:(int)v add:B:(int)w
{
bigintobjvec_c c;
bigintobj_c ac;
assert ([scalarZero sameClass:a] && [self sameClass:B] && v * v == 1 && w * w == 1);
bigintobjvec_oomulscadd (&c, bigintobjvec_id2t (self), bigintobj_id2ref (a, &ac), v, bigintobjvec_id2t (B), w, bigintobjvec_getargs (self));
return bigintobjvec_c2id (self, &c);
}
- _multiplyScalar:a:(int)v add:B multiplyScalar:b:(int)w
{
bigintobjvec_c c;
bigintobj_c ac, bc;
assert ([scalarZero sameClass:a] && [self sameClass:B] && [scalarZero sameClass:b] && v * v == 1 && w * w == 1);
bigintobjvec_oomulscaddmulsc (&c, bigintobjvec_id2t (self), bigintobj_id2ref (a, &ac), v, bigintobjvec_id2t (B), bigintobj_id2ref (b, &bc), w, bigintobjvec_getargs (self));
return bigintobjvec_c2id (self, &c);
}
@end