Question: Create a sparse matrix vector with a linked list then creat a sparese matrix using linked list. I have done problem 1 and tested it

Create a sparse matrix vector with a linked list then creat a sparese matrix using linked list.

I have done problem 1 and tested it , which is to create LLsparseVector class, now I'm stuck on problem 2. I have started it but not sure if im on the right track at all. My exact problem is, I'm not sure how to: "RowHead nodes correspond to nonzero rows. Each rowhead node stores a LLSparseVec, storing a nonzero row. It also has a pointer to the next rowhead". I undertand the logic why we would want to use for each row a LLSparseVec, but how can a row head node store a LLSparseVec? For example giving this input in a text file (that woudl be with out doing any operations yet, but that's okay I havent gotten that far yet). Also the arrayMain class is just an example given please disregard it as it is not part of the project. Thank you in advance

MATRIX 10 20 SET 0 11 1 SET 0 8 1 SET 8 2 1 CLEAR 0 8 CLEAR 2 8 SET 8 11 1 END

my output would be :

FINAL_MATRIX NROWS 10 NCOLS 20 NELEMS 3 NUM_ROWS 2 ROW 0 RIDX 0 CIDX 11 VAL 1 ROW 8 RIDX 8 CIDX 2 VAL 1 RIDX 8 CIDX 11 VAL 1 END

This are the exact instructions:

Problem 1: Sparse Vector Using Linked List (5 pts)

Implement the linked list sparse vector class (LLSparseVec.java) so that LLMainClass can be executed.

Nodes in the linked list are nonzero elements of the vector, sorted according to their indices. The length of a vector is specified at construction.

When an element is set to zero, the corresponding node should be removed!

Implement the constructor, accessor methods, getElement, setElement, clearElement, getAllIndices, getAllValues. In otherwords, when LLMainClass is called using VEC argument and with a single input file, the program should be able to run correctly and give the same output as ArrayMainClass.

Implement both the addition, subtraction and multiplication methods in LLSparseVec. The method subtraction(otherV) means the current vector minus otherV.

The algorithm has to be O(m), in which m is the maximum number of nonzero elements in a vector (length of the list). To achieve this, you cannot simply use get and set in Problem 1. Only algorithms with O(m) complexity will get credits. The smart-merge method in HW1 is a good place to start. But note the difference here.

All operations return a new sparse vector object, storing the result.

If the two vectors length do not match, return a null object.

When LLMainClass is called using VEC argument and with multiple input files, the program should be able to run correctly and give the same output as ArrayMainClass.

Examples:

Problem 2: Sparse Matrix Using Linked List (5 pts)

Implement the linked list sparse matrix class (LLSparseMat.java) so that LLMainClass can be executed with MAT argument.

RowHead nodes correspond to nonzero rows. Each rowhead node stores a LLSparseVec, storing a nonzero row. It also has a pointer to the next rowhead.

When a row becomes empty (no nonzero elements), the rowhead should be removed.

Implement the constructor, accessor methods:

getElement, setElement, clearElement, numElements (returns number of non-zero elements).

getRowIndices returns an array of indices of rows with nonzero elements.

getOneRowColIndices returns an array of nonzero column indices of the row. Use LLSparseVec.getAllIndices().

getOneRowValues returns an array of nonzero values. Use LLSparseVec.getAllValues().

NOTE that these methods should all be linear to the number of nonzero rows or nonzero elements.

Sanity check: when LLMainClass is called using MAT argument and with a single input file, the program should be able to run correctly and give the same output as ArrayMainClass.

Problem 3: Sparse Matrix Operation Linked List (5 points)

Implement the addition, subtraction and multiplication methods in LLSparseM.

The algorithm has to be O(m), in which m is the maximum number of nonzero elements in a matrix. To achieve this, you cannot simply use get and set in Problem 3. Only algorithms with O(m) complexity will get credits.

All operations return a new sparse matrix object, storing the result. The method subtraction(otherM) means the current vector minus otherM.

If the two matrices dimensions (nrows, ncols) do not match, return a null object.

When LLMainClass is called using MAT argument and with multiple input files, the program should be able to run correctly and give the same output as ArrayMainClass.

public interface SparseVec {

// problem 1

int getLength(); //return the length of the vector

int numElements(); //return total number of nonzero elements in the vector

int getElement(int idx); //return the element at a given idx

void clearElement(int idx); //set the element at idx to zero

void setElement(int idx, int val); //set the element at idx to val

// get all nonzero indices

int[] getAllIndices();

// get all nonzero values

int[] getAllValues();

SparseVec addition(SparseVec otherV); // this vector + otherV

// return a new vector storing the result

SparseVec subtraction(SparseVec otherV); // this vector - otherV

// return a new vector storing the result

SparseVec multiplication(SparseVec otherV); // this matrix .* otherV

// return a new vector storing the result

}

public interface SparseM {

// problem 2

int nrows(); //return number of rows

int ncols(); //return number of columns

int numElements(); //return total number of nonzero elements in the matrix

int getElement(int ridx, int cidx); //return the element at a given entry (ridx, cidx),

void clearElement(int ridx, int cidx); //set the element at (ridx,cidx) to zero

void setElement(int ridx, int cidx, int val); //set the element at (ridx,cidx) to val

// get indices of non-empty rows, sorted

int[] getRowIndices();

// get indices of non-empty cols, sorted

int[] getOneRowColIndices(int ridx);

// get values of a given row

int[] getOneRowValues(int ridx);

// methods for problem 3

SparseM addition(SparseM otherM); // this matrix + otherM

// return a new matrix storing the result

SparseM subtraction(SparseM otherM); // this matrix - otherM

// return a new matrix storing the result

SparseM multiplication(SparseM otherM); // this matrix .* with otherM

// return a new matrix storing the result

}

/*------ This Node class is to be used in a doubly linked list ---*/

public class Node

{

private int data;

private int index;

private int ridx;

private Node prev; // reference to the previous node in the list

private Node next; // reference to the succeeding node in the list

// Default constructor

public Node() {};

// Constructor that sets up a prev and a next.

public Node(int idx,int d, Node p, Node n)

{

index = idx;

data = d;

prev = p;

next = n;

}

// Constructor that holds row index and links to a previous and next row index

public Node(int ridx, Node prevRidx, Node nextRidx)

{

this.ridx = ridx;

prev = prevRidx;

next = nextRidx;

}

public int getData() { return data; }

public int getIndex() { return index; }

public int getRidx() { return ridx; }

public Node getPrev() { return prev; }

public Node getNext() { return next; }

public void setData(int d) { data = d; }

public void setPrev(Node p) { prev = p; }

public void setNext(Node n) { next = n; }

}// ---------------- End Node class ----------

public class LLSparseVec implements SparseVec

{

private int len; // length of LLVector

private int nElements = 0; // number of nonzero elements, set to zero;

private Node header = null; // header sentinel, dummy node

private Node trailer = null; // trailer sentinel, dummy node

// Constructor

public LLSparseVec(int len)

{

if( len

this.len = len;

//Create the Vector

header = new Node(); // creating header

trailer = new Node(); // creating trailer

header.setNext(trailer); // header is followed by trailer

trailer.setPrev(header); // trailer is preceded by header

}

// check if the given index is out of bounds

private boolean outOfBounds(int idx)

{

return((idx = len));

}

@Override

public int getLength() {

// TODO Auto-generated method stub

return len;

}

@Override

public int numElements() {

// TODO Auto-generated method stub

return nElements;

}

@Override

public int getElement(int idx) {

// TODO Auto-generated method stub

// If index is out of bounds or list empty exit

if(outOfBounds(idx))

return Integer.MIN_VALUE;

Node temp = header.getNext();

while(temp != trailer)

{

if(idx == temp.getIndex())

return temp.getData();

// If index is

if(idx

break;

temp = temp.getNext();

}

return 0;

}

@Override

public void clearElement(int idx) {

// TODO Auto-generated method stub

if(outOfBounds(idx)) // If index out of bounds exit

return;

Node temp = header.getNext();

Node predecessor;

Node sucessor;

while(temp != trailer)

{

if(idx == temp.getIndex())

{

predecessor = temp.getPrev();

sucessor = temp.getNext();

predecessor.setNext(sucessor);

sucessor.setPrev(predecessor);

nElements--;

}

// If index is

if(idx

break;

temp = temp.getNext();

}

}

@Override

public void setElement(int idx, int val) {

//System.out.println(" idx " + idx + " value " + val);

// TODO Auto-generated method stub

if(outOfBounds(idx))

throw new IllegalStateException("ERROR, index out of bounds.");

// If the list is empty add between header and trailer.

else if(numElements() == 0 && val != 0)

addBetween(idx, val, header, trailer);

// If val = 0 remove the index

else if(val == 0)

clearElement(idx);

// In the case that index added is smaller than the first node's index

else if ( idx

addBetween(idx, val, header, header.getNext());

// In the case the index added is greater than the last node's index

else if ( idx > trailer.getPrev().getIndex())

addBetween(idx, val, trailer.getPrev(), trailer);

else

{

Node temp = header.getNext();

while(temp != trailer)

{

if( idx == temp.getIndex() && val != temp.getData())

{

temp.setData(val);

return;

}

else if(idx == temp.getIndex() && val == temp.getData() )

return;

if( idx

{

addBetween(idx, val, temp.getPrev(), temp);

return;

}

temp = temp.getNext();

}

}

}

@Override

public int[] getAllIndices() {

// TODO Auto-generated method stub

int[] idx = new int[nElements];

Node tempIdx = header.getNext();

for(int i = 0; tempIdx != trailer; i++)

{

idx[i] = tempIdx.getIndex();

tempIdx = tempIdx.getNext();

}

return idx;

}

@Override

public int[] getAllValues() {

// TODO Auto-generated method stub

int[] val = new int[nElements];

Node tempVal = header.getNext();

for(int i = 0; tempVal != trailer; i++)

{

val[i] = tempVal.getData();

tempVal = tempVal.getNext();

}

return val;

}

private void addBetween(int idx, int val, Node predecessor, Node successor)

{ // create and link a new node

Node newest = new Node (idx, val, predecessor, successor);

predecessor.setNext(newest);

successor.setPrev(newest);

nElements++;

}

@Override

public SparseVec addition(SparseVec otherV) {

// TODO Auto-generated method stub

if(this.len != otherV.getLength())

return null; //exit if lengths not even.

SparseVec newVec = new LLSparseVec(len);

int temp;

for(int i = 0; i

{

temp = this.getElement(i) + otherV.getElement(i);

newVec.setElement(i, temp);

}

return newVec;

}

@Override

public SparseVec subtraction(SparseVec otherV) {

// TODO Auto-generated method stub

if(this.len != otherV.getLength())

return null; //exit if lengths not even.

SparseVec newVec = new LLSparseVec(len);

int temp;

for(int i = 0; i

{

temp = this.getElement(i) - otherV.getElement(i);

newVec.setElement(i, temp);

}

return newVec;

}

@Override

public SparseVec multiplication(SparseVec otherV) {

// TODO Auto-generated method stub

if(this.len != otherV.getLength())

return null; //exit if lengths not even.

SparseVec newVec = new LLSparseVec(len);

int temp;

for(int i = 0; i

{

temp = this.getElement(i) * otherV.getElement(i);

newVec.setElement(i, temp);

}

return newVec;

}

}

import java.util.Scanner;

import java.io.File;

public class LLMainClass {

public static SparseM ParseMatrix(String file_name){

Scanner sc = null;

String tmps;

SparseM M = null;

try {

sc = new Scanner(new File(file_name));

while (sc.hasNext()) {

tmps = sc.next();

if(tmps.equals("MATRIX")){

// initialize the matrix

int nr = sc.nextInt();

int nc = sc.nextInt();

M = new LLSparseM(nr,nc);

}else if(tmps.equals("END")){

// finished, return the matrix

sc.close();

return M;

}else if(tmps.equals("SET")){

// set an element

int ridx = sc.nextInt(); // row index

int cidx = sc.nextInt(); // col index

int val = sc.nextInt(); // value

M.setElement(ridx, cidx, val);

}else if(tmps.equals("CLEAR")){

// clear an element

int ridx = sc.nextInt(); // row index

int cidx = sc.nextInt(); // col index

M.clearElement(ridx, cidx);

}

}

sc.close();

return M;

} catch (Exception e) {

return null;

}

}

public static SparseVec ParseVector(String file_name){

Scanner sc = null;

String tmps;

SparseVec V = null;

try {

sc = new Scanner(new File(file_name));

while (sc.hasNext()) {

tmps = sc.next();

if(tmps.equals("VECTOR")){

// initialize the matrix

int len = sc.nextInt();

V = new LLSparseVec(len);

}else if(tmps.equals("END")){

// finished, return the matrix

sc.close();

return V;

}else if(tmps.equals("SET")){

// set an element

int idx = sc.nextInt(); // index

int val = sc.nextInt(); // value

V.setElement(idx, val);

}else if(tmps.equals("CLEAR")){

// clear an element

int idx = sc.nextInt(); // index

V.clearElement(idx);

}

}

sc.close();

return V;

} catch (Exception e) {

return null;

}

}

public static void main(String[] args) {

try{

int n = args.length;

if(n

System.out.println("java LLMainClass VEC/MAT File1 A/M File2 ...");

return;

}

String fname;

String operator;

String dtype = args[0]; // matrix or vector

if(dtype.equals("VEC")){

fname = args[1];

SparseVec V = ParseVector(fname); // read V from the first file

if(V == null){

// if invalid input file, print NULL and exit

System.out.println("NULL: Illegal Input File "+fname);

return;

}

SparseVec tmpV;

for(int i = 2; i

operator = args[i];

fname = args[i+1];

tmpV = ParseVector(fname); // read tmpM from the next file

if(tmpV == null) // if the file is invalid, skip

{ System.out.println("NULL: Illegal Input File "+fname);

return;

}

if(operator.equals("A"))

V = V.addition(tmpV); // add tmpV to V

else if(operator.equals("S"))

V = V.subtraction(tmpV); // multiply tmpV to V

else if(operator.equals("M"))

V = V.multiplication(tmpV); // multiply tmpV to V

else{

System.out.println("NULL: Illegal operator: " + operator );

return;

}

if(V == null) // operation failed

{ System.out.println("NULL: Operator "+operator+" Failed, Fname "+fname);

return;

}

}

// output the final matrix

System.out.println("Final_Vector");

int[] idx = V.getAllIndices();

int[] val = V.getAllValues();

int len, ne;

len = V.getLength(); // length

ne = V.numElements(); // number of elements

System.out.println("LENGTH " + len + " NELEMS " + ne);

for(int i = 0; i

System.out.println("IDX " + idx[i] + " VAL " + val[i]);

System.out.println("END");

}else if(dtype.equals("MAT")){

fname = args[1];

SparseM M = ParseMatrix(fname); // read M from the first file

if(M == null){

// if invalid input file, print NULL and exit

System.out.println("NULL: Illegal Matrix Input, Fname " + fname);

return;

}

SparseM tmpM;

for(int i = 2; i

operator = args[i];

fname = args[i+1];

tmpM = ParseMatrix(fname); // read tmpM from the next file

if(tmpM == null) // if the file is invalid, skip

{ System.out.println("NULL: Illegal Input, Fname " + fname);

return;

}

if(operator.equals("A"))

M = M.addition(tmpM); // add tmpM to M

else if(operator.equals("S"))

M = M.subtraction(tmpM); // multiply tmpV to V

else if(operator.equals("M"))

M = M.multiplication(tmpM); // multiply tmpM to M

else{

System.out.println("NULL: Illegal operator: " + operator );

return;

}

if(M == null) // if the file is invalid, skip

{ System.out.println("NULL: Operation "+operator + " Failed, Fname "+ fname);

return;

}

}

// output the final matrix

System.out.println("FINAL_MATRIX");

int nr, nc, ne;

nr = M.nrows(); // number of rows

nc = M.ncols(); // number of columns

ne = M.numElements(); // number of elements

System.out.println("NROWS " + nr + " NCOLS " + nc + " NELEMS " + ne);

// print the matrix in rows

int[] ridx_list = M.getRowIndices();

System.out.println("NUM_ROWS "+ridx_list.length);

for(int ridx : ridx_list){

System.out.println("ROW "+ridx);

int[] one_row_cidx_list = M.getOneRowColIndices(ridx);

int[] one_row_vals_list = M.getOneRowValues(ridx);

for(int i = 0; i

System.out.println("RIDX "+ridx+" CIDX " + one_row_cidx_list[i] + " VAL " + one_row_vals_list[i]);

}

System.out.println("END");

}else{

System.out.println("The first argument has to be either VEC or MAT, meaning the data is Vector or Matrix");

return;

}

} catch (Exception e) {

System.out.println("NULL: Something is wrong");

return;

}

}

}

public class LLSparseM implements SparseM

{

private int nrows, ncols;

private int nElements = 0; // number of nonzero elements, initialized to be zero

private Node header;

private Node trailer;

// Constructor

public LLSparseM(int nr, int nc){

if(nr

if(nc

nrows = nr;

ncols = nc;

header = new Node(); // creating header

trailer = new Node(); // creating trailer

header.setNext(trailer); // header is followed by trailer

trailer.setPrev(header); // trailer is preceded by header

}

// check if the given (ridx, cidx) is out of bounds

private boolean outOfBounds(int ridx, int cidx){

return((ridx = nrows) || (cidx = ncols));

}

@Override

public int nrows() {

// TODO Auto-generated method stub

return 0;

}

@Override

public int ncols() {

// TODO Auto-generated method stub

return 0;

}

@Override

public int numElements() {

// TODO Auto-generated method stub

return 0;

}

@Override

public int getElement(int ridx, int cidx) {

// TODO Auto-generated method stub

return 0;

}

@Override

public void clearElement(int ridx, int cidx) {

// TODO Auto-generated method stub

}

@Override

public void setElement(int ridx, int cidx, int val) {

// TODO Auto-generated method stub

if(outOfBounds(ridx,cidx))

return;

else if(val == 0)

clearElement(ridx,cidx);

// In the case that there is no next row, matrix is empty

else if (header.getNext() == trailer && val != 0)

addBetweenRow(ridx, cidx, val, header, trailer);

else if( ridx

addBetweenRow(ridx, cidx, val, header, header.getNext());

// In the case that row index is greater than the last row in the list.

else if( ridx > trailer.getPrev().getRidx() )

addBetweenRow(ridx, cidx, val, trailer.getPrev(), trailer);

else

{

}

}

public void addBetweenRow(int ridx, int cidx, int val, Node prevRidx, Node nextRidx)

{

LLSparseVec newest = new LLSparseVec(ncols);

prevRidx.setNext(newest);

newest.setElement(cidx, val);

}

@Override

public int[] getRowIndices() {

// TODO Auto-generated method stub

return null;

}

@Override

public int[] getOneRowColIndices(int ridx) {

// TODO Auto-generated method stub

return null;

}

@Override

public int[] getOneRowValues(int ridx) {

// TODO Auto-generated method stub

return null;

}

@Override

public SparseM addition(SparseM otherM) {

// TODO Auto-generated method stub

return null;

}

@Override

public SparseM subtraction(SparseM otherM) {

// TODO Auto-generated method stub

return null;

}

@Override

public SparseM multiplication(SparseM otherM) {

// TODO Auto-generated method stub

return null;

}

}

Create a sparse matrix vector with a linked list then creat a

First Row 20 x 30 nElements-7 | idx = 7 val-1 idx 11 val 99 rids 5 idx- 21 val 11 idx = 3 val 2 idx- 11 val-10 idx - 21 val--2 val12 First Row 20 x 30 nElements-7 | idx = 7 val-1 idx 11 val 99 rids 5 idx- 21 val 11 idx = 3 val 2 idx- 11 val-10 idx - 21 val--2 val12

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!