Lab 7: object vec_t

Objectives

To implement and exercise the vec_t object.

Assignment

  1. Following the class notes, define the vec_t object in the vector.h interface, providing the following class member functions:
      // constructors (overloaded)
    - (id)      init: (double) x;
    - (id)      init: (double) x: (double) y;
    - (id)      init: (double) x: (double) y: (double) z;
    
      // accessor/mutator
    - (double)  get: (int) i;
    - (void)    set: (int) i: (double) d;
    - (void)    set: (double) x: (double) y: (double) z;
    
      // operators
    - (vec_t *) plus: (vec_t *) v;
    - (vec_t *) minus: (vec_t *) v;
    - (vec_t *) scale: (double) d;
    - (vec_t *) unit;
    
    - (double)  dot: (vec_t *) v;
    - (double)  len;
    
      // friends
    - (void)    write: (FILE *) f: (char *) msg;
    	
  2. All member functions (a.k.a. methods), including dot() and len(), must be implemented in the vec_t implementation vector.m
  3. Your code should be such that the following main() routine works unaltered:
    #import <Foundation/Foundation.h>
    
    #import <stdio.h>
    #import <vector.h>
    
    //---- program section ----
    
    int main(int argc, const char *argv[])
    {
            NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
            vec_t *v1 = [(vec_t *)[vec_t alloc] init: 3.0: 4.0: 5.0];
            vec_t *v2 = [(vec_t *)[vec_t alloc] init];
            vec_t *v3 = nil, *v4 = nil, *v5 = [v1 copy];
    
      NSLog(@"main start");
    
    //[v1 set: 3.0:  4.0:  5.0];
      [v2 set: 4.0: -1.0:  2.0];
    
      [v1 write: stderr: "v1 is:"];
      [v2 write: stderr: "v2 is:"];
    
      // v3 allocated by minus operator, which we retain (must release later)
      v3 = [[v2 minus: v1] retain];
    
      [v3 write: stderr: "v2 - v1 is:"];
    
      // example of "transient" memory use where we don't retain memory
      [[v2 minus: v1] write: stderr: "v2 - v1 is:"];
    
      fprintf(stderr,"v1 dot v2 is: %f\n", [v1 dot: v2]);
    
      fprintf(stderr,"length of v1 is: %f\n", [v1 len]);
    
      // memory leak?  no...scale returns an autorelease object
      [[v1 scale: 1./[v1 len]] write: stderr: "v1 scaled by 1/length is:"];
    
      // memory leak?  no, unit returns autorelease object whcih we retain
      v4 = [[v1 unit] retain];
      [v4 write: stderr: "unit vector in v1 direction:"];
    
      [v1 release];
      [v2 release];
      [v3 release];
      [v4 release];
    
      [v5 write: stderr: "v5 is:"];
      [v5 release];
    
      [pool drain];
    
      return 0;
    }
    	
  4. Use the following Makefile to compile the vector library into a libvec.a library that other programs can use (be careful where tabs are required!).
    
    .SUFFIXES: .m
    
    UNAME   = $(shell uname)
    
    CC      = gcc
    
    ifeq ($(UNAME),Linux)
    #CFLAGS = -g -fconstant-string-class=NSConstantString
    CFLAGS  = -g `gnustep-config --objc-flags`
    INCLUDE = -I. -I/usr/include/GNUstep
    LDFLAGS = -L. -L/usr/lib -L/usr/lib/GNUstep
    LDLIBS  = -lgnustep-base
    endif
    
    ifeq ($(UNAME),Darwin)
    #CFLAGS = -g -x objective-c -arch i386 -mmacosx-version-min=10.5
    #CFLAGS = -g -arch i386 -mmacosx-version-min=10.5
    CFLAGS  = -g -mmacosx-version-min=10.6
    INCLUDE = -I.
    LDFLAGS = -L. -L/usr/lib
    LDLIBS  = -framework Foundation
    endif
    
    .m.o:
            $(CC) -c $(INCLUDE) $(CFLAGS) $<
    
    OBJS = \
    vector.o \
    main.o
    
    all: main
    
    main: main.m $(OBJS)
    #       $(CC) $(CFLAGS) $(INCLUDE) -o $@ $(OBJS) $(LDFLAGS) $(LDLIBS)
            $(CC) -o $@ $(OBJS) $(LDFLAGS) $(LDLIBS)
    
    clean:
            rm -f *.o core
            rm -f main
    	
  5. Sample output (note that the first line with the timestamp will be different):
    2013-01-15 13:25:56.652 main[47843:903] main start
    v1 is:   3.000   4.000   5.000
    v2 is:   4.000  -1.000   2.000
    v2 - v1 is:   1.000  -5.000  -3.000
    v2 - v1 is:   1.000  -5.000  -3.000
    v1 dot v2 is: 18.000000
    length of v1 is: 7.071068
    v1 scaled by 1/length is:   0.424   0.566   0.707
    unit vector in v1 direction:   0.424   0.566   0.707
    v5 is:   3.000   4.000   5.000
    	

Turn in

Turn in all of your code, in one tar.gz archive of your lab07/ directory, including:
  1. A README file containing
    1. Course id--section no
    2. Name
    3. Lab description
    4. Brief solution description (e.g., program design, description of algorithm, etc., however appropriate).
    5. Lessons learned, identified interesting features of your program
    6. Any special usage instructions
  2. Makefile
  3. source code (.h headers and .m source)
  4. object code (do a make clean before tar)

How to hand in

See submit notes.