
/*
 * Computer Algebra Kit (c) 1993,98 by Comp.Alg.Objects.  All Rights Reserved.
 * $Id: vectorc.m,v 1.7 1998/11/13 09:45:49 stes Exp $
 */

#include "cakit.h"

@implementation vectorc
- (int)numScalars			 {
  [self subclassResponsibility:_cmd];
  return 0;
}
- numScalars:(int)n			 {
  [self subclassResponsibility:_cmd];
  return self;
}
- capacity:(int)n			 {
  [self subclassResponsibility:_cmd];
  return self;
}
- insertScalar:aScalar			 {
  [self subclassResponsibility:_cmd];
  return self;
}
- insertScalar:aScalar at:(int)i	 {
  [self subclassResponsibility:_cmd];
  return self;
}
- removeScalar				 {
  [self subclassResponsibility:_cmd];
  return self;
}
- removeScalarAt:(int)i			 {
  [self subclassResponsibility:_cmd];
  return self;
}
- placeScalar:aScalar at:(int)i		 {
  [self subclassResponsibility:_cmd];
  return self;
}
- replaceScalarAt:(int)i with:aScalar	 {
  [self subclassResponsibility:_cmd];
  return self;
}
- eachScalar				 {
  [self subclassResponsibility:_cmd];
  return self;
}

- (BOOL)sameClass:b
{
  return isa == [b class] && [[self scalarZero] isEqual:[b scalarZero]];
}


- (float) floatValueAt:(int)i
{
  float res;
  id seq = [self eachScalar];

  res = [[seq at:i] floatValue];
  [seq free];
  return res;
}

- (int) intValueAt:(int)i
{
  int res;
  id seq = [self eachScalar];

  res = [[seq at:i] intValue];
  [seq free];
  return res;
}


- (BOOL) isZero
{
  id seq;
  int i, n = [self numScalars];

  seq = [self eachScalar];
  for (i = 0; i < n; i++)
    if ([[seq at:i] notZero]) {
      [seq free];
      return NO;
    }
  [seq free];
  return YES;
}

- negate
{
  id c, seq;
  int i, n = [self numScalars];

  c = [self numScalars:n];
  seq = [self eachScalar];
  for (i = 0; i < n; i++)
    [c placeScalar:[[seq at:i] negate] at:i];

  [seq free];
  return c;
}

- double
{
  id c, seq;
  int i, n = [self numScalars];

  c = [self numScalars:n];
  seq = [self eachScalar];
  for (i = 0; i < n; i++)
    [c placeScalar:[[seq at:i] double] at:i];

  [seq free];
  return c;
}

- add:b
{
  id c, A, B;
  int i, n = [self numScalars];

  assert(self != b && [b numScalars] == n);
  c = [self numScalars:n];
  A = [self eachScalar];
  B = [b eachScalar];
  for (i = 0; i < n; i++)
    [c placeScalar:[[A at:i] add:[B at:i]] at:i];
  [A free];
  [B free];

  return c;
}

- subtract:b
{
  id c, A, B;
  int i, n = [self numScalars];

  assert(self != b && [b numScalars] == n);
  c = [self numScalars:n];
  A = [self eachScalar];
  B = [b eachScalar];
  for (i = 0; i < n; i++)
    [c placeScalar:[[A at:i] subtract:[B at:i]] at:i];
  [A free];
  [B free];

  return c;
}


- multiplyScalar:t
{
  id c, seq;
  int i, n = [self numScalars];

  c = [self numScalars:n];

  seq = [self eachScalar];
  for (i = 0; i < n; i++)
    [c placeScalar:[[seq at:i] multiply:t] at:i];
  [seq free];

  return c;
}

- divideScalar:t
{
  id c, seq;
  int i, n = [self numScalars];

  c = [self numScalars:n];

  seq = [self eachScalar];
  for (i = 0; i < n; i++) {
    id q = [[seq at:i] divide:t];

    if (q)
      [c placeScalar:q at:i];
    else {
      [seq free];
      [c free];
      return nil;
    }
  }
  [seq free];

  return c;
}


- dotSquare
{
  id seq, sum = [[self scalarZero] zero];
  int i, n = [self numScalars];

  seq = [self eachScalar];
  for (i = 0; i < n; i++) {
    id t = [[seq at:i] square];

    sum = [sum addSelf:t];
    [t free];			/* addSelf:square: ?? */
  }
  [seq free];
  return sum;
}

- dotMultiply:aVector
{
  id A, B, sum = [[self scalarZero] zero];
  int i, n = [self numScalars];

  assert([aVector numScalars] == n);
  A = [self eachScalar];
  B = [aVector eachScalar];
  for (i = 0; i < n; i++) {
    id t = [[A at:i] multiply:[B at:i]];

    sum = [sum addSelf:t];
    [t free];			/* addSelf:multiply: ?? */
  }
  [A free];
  [B free];
  return sum;
}

@end

