blob: a3b2c5204faf2c2c2ba31b4899e7990824d3b3ed [file] [log] [blame]
package org.apache.samoa.instances;
/*
* #%L
* SAMOA
* %%
* Copyright (C) 2014 - 2015 Apache Software Foundation
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* Class for storing the information of the attributes.
* It stores only information about discrete attributes and suppose that
* the default attribute is numeric.
*/
public class AttributesInformation implements Serializable {
/**
* The attribute information.
*/
protected Attribute[] attributes;
protected int[] indexValues;
/**
* The number of attributes.
*/
protected int numberAttributes;
/**
* The attribute used for default for numerical values
*/
protected Attribute defaultNumericAttribute;
public AttributesInformation(AttributesInformation chunk) {
this.attributes = chunk.attributes.clone();
this.indexValues = chunk.indexValues.clone();
this.numberAttributes = chunk.numberAttributes;
}
public AttributesInformation(Attribute[] v, int[] i, int numberAttributes) {
this.attributes = v;
this.indexValues = i;
this.numberAttributes = numberAttributes;
}
public AttributesInformation(Attribute[] v, int numberAttributes) {
this.attributes = v;
this.indexValues = new int[numberAttributes];
for (int i = 0; i < numberAttributes; i++) {
this.indexValues[i] = i;
}
this.numberAttributes = numberAttributes;
}
public AttributesInformation(List<Attribute> v, int numberAttributes) {
this.attributes = new Attribute[numberAttributes];
this.indexValues = new int[numberAttributes];
for (int i = 0; i < numberAttributes; i++) {
this.indexValues[i] = i;
this.attributes[i] = v.get(i);
}
this.numberAttributes = numberAttributes;
}
public AttributesInformation() {
this.attributes = null;
this.indexValues = null;
this.numberAttributes = 0;
this.defaultNumericAttribute = null;
}
/**
* Attribute.
*
* @param indexAttribute the index Attribute
* @return the attribute
*/
public Attribute attribute(int indexAttribute) {
if (this.attributes == null) {
//All attributes are numeric
return defaultNumericAttribute();
}
int location = locateIndex(indexAttribute);
if (location == -1) {
//if there is not attribute information, it is numeric
return defaultNumericAttribute();
}
return attributes[location];
}
/*public void add(Attribute attribute, int value) {
this.attributes.add(attribute);
this.indexValues.add(value);
}*/
/**
* Sets the attribute information.
*
* @param v the new attribute information
*/
public void setAttributes(Attribute[] v) {
this.attributes = v;
this.numberAttributes = v.length;
this.indexValues = new int[numberAttributes];
for (int i = 0; i < numberAttributes; i++) {
this.indexValues[i] = i;
}
}
/**
* Locates the greatest index that is not greater than the given index.
*
* @return the internal index of the attribute index. Returns -1 if no index
* with this property could be found
*/
public int locateIndex(int index) {
int min = 0;
int max = this.indexValues.length - 1;
if (max == -1) {
return -1;
}
// Binary search
while ((this.indexValues[min] <= index) && (this.indexValues[max] >= index)) {
int current = (max + min) / 2;
if (this.indexValues[current] > index) {
max = current - 1;
} else if (this.indexValues[current] < index) {
min = current + 1;
} else {
return current;
}
}
if (this.indexValues[max] < index) {
return max;
} else {
return min - 1;
}
}
private Attribute defaultNumericAttribute() {
if (this.defaultNumericAttribute == null) {
this.defaultNumericAttribute = new Attribute("default");
}
return this.defaultNumericAttribute;
}
public void setAttributes(Attribute[] v, int[] indexValues) {
this.attributes = v;
this.numberAttributes = v.length;
this.indexValues = indexValues;
}
public void deleteAttributeAt(int position) {
int index = locateIndex(position);
this.numberAttributes--;
if ((index >= 0) && (indexValues[index] == position)) {
int[] tempIndices = new int[indexValues.length - 1];
Attribute[] tempValues = new Attribute[attributes.length - 1];
System.arraycopy(indexValues, 0, tempIndices, 0, index);
System.arraycopy(attributes, 0, tempValues, 0, index);
for (int i = index; i < indexValues.length - 1; i++) {
tempIndices[i] = indexValues[i + 1] - 1;
tempValues[i] = attributes[i + 1];
}
indexValues = tempIndices;
attributes = tempValues;
} else {
int[] tempIndices = new int[indexValues.length];
Attribute[] tempValues = new Attribute[attributes.length];
System.arraycopy(indexValues, 0, tempIndices, 0, index + 1);
System.arraycopy(attributes, 0, tempValues, 0, index + 1);
for (int i = index + 1; i < indexValues.length; i++) {
tempIndices[i] = indexValues[i] - 1;
tempValues[i] = attributes[i];
}
indexValues = tempIndices;
attributes = tempValues;
}
}
public void insertAttributeAt(Attribute attribute, int position) {
if ((position < 0) || (position > this.numberAttributes)) {
throw new IllegalArgumentException("Can't insert attribute: index out "
+ "of range");
}
int index = locateIndex(position);
this.numberAttributes++;
if ((index >= 0) && (indexValues[index] == position)) {
int[] tempIndices = new int[indexValues.length + 1];
Attribute[] tempValues = new Attribute[attributes.length + 1];
System.arraycopy(indexValues, 0, tempIndices, 0, index);
System.arraycopy(attributes, 0, tempValues, 0, index);
tempIndices[index] = position;
tempValues[index] = attribute;
for (int i = index; i < indexValues.length; i++) {
tempIndices[i + 1] = indexValues[i] + 1;
tempValues[i + 1] = attributes[i];
}
indexValues = tempIndices;
attributes = tempValues;
} else {
int[] tempIndices = new int[indexValues.length + 1];
Attribute[] tempValues = new Attribute[attributes.length + 1];
System.arraycopy(indexValues, 0, tempIndices, 0, index + 1);
System.arraycopy(attributes, 0, tempValues, 0, index + 1);
tempIndices[index + 1] = position;
tempValues[index + 1] = attribute;
for (int i = index + 1; i < indexValues.length; i++) {
tempIndices[i + 1] = indexValues[i] + 1;
tempValues[i + 1] = attributes[i];
}
indexValues = tempIndices;
attributes = tempValues;
}
}
}