package tudelft.mentalhealth.perfectfit; import java.io.IOException; import java.util.Arrays; import java.util.Objects; /** * Normalized characteristics of a person. Use * {@link #normalize(double, double, double, double, double, double, double, double, double, double)} * is you have non-normalized characterists eg from the form */ public class Characteristics { private final double godin_activity; private final double exercise_se; private final double exercise_identity; private final double extraversion; private final double ttm_pa; private final double openness; private final double sitting_weekend; private final double age; private final double household_income; private final double household_size; /** * * @param godin_activity normalized godin value from the questionnaire * form * @param exercise_se normalized exercise_se value from the * questionnaire form * @param exercise_identity normalized exercise_identity value from the * questionnaire form * @param extraversion normalized extraversion value from the * questionnaire form * @param ttm_pa normalized ttm_pa value from the questionnaire * form * @param openness normalized openness value from the questionnaire * form * @param sitting_weekend normalized sitting_weekend value from the * questionnaire form * @param age normalized age value from the questionnaire form * @param household_income normalized household_income value from the * questionnaire form * @param household_size normalized household_size value from the * questionnaire form */ public Characteristics(double godin_activity, double exercise_se, double exercise_identity, double extraversion, double ttm_pa, double openness, double sitting_weekend, double age, double household_income, double household_size) throws IOException { if (notnormal(godin_activity) || notnormal(exercise_se) || notnormal(exercise_identity) || notnormal(extraversion) || notnormal(ttm_pa) || notnormal(openness) || notnormal(sitting_weekend) || notnormal(age) || notnormal(household_income) || notnormal(household_size)) throw new IllegalArgumentException("values are not normalized"); this.godin_activity = godin_activity; this.exercise_se = exercise_se; this.exercise_identity = exercise_identity; this.extraversion = extraversion; this.ttm_pa = ttm_pa; this.openness = openness; this.sitting_weekend = sitting_weekend; this.age = age; this.household_income = household_income; this.household_size = household_size; } /** * * @param godin_activity non-normalized godin value from the * questionnaire form * @param exercise_se non-normalized exercise_se value from the * questionnaire form * @param exercise_identity non-normalized exercise_identity value from the * questionnaire form * @param extraversion non-normalized extraversion value from the * questionnaire form * @param ttm_pa non-normalized ttm_pa value from the * questionnaire form * @param openness non-normalized openness value from the * questionnaire form * @param sitting_weekend non-normalized sitting_weekend value from the * questionnaire form * @param age non-normalized age value from the questionnaire * form * @param household_income non-normalized household_income value from the * questionnaire form * @param household_size non-normalized household_size value from the * questionnaire form * @throws IOException if bad values are given */ public static Characteristics normalize(double godin_activity, double exercise_se, double exercise_identity, double extraversion, double ttm_pa, double openness, double sitting_weekend, double age, double household_income, double household_size) throws IOException { return new Characteristics(n(godin_activity, 0, 2), n(exercise_se, 0, 100), n(exercise_identity, 0, 3.7000000000000002), n(extraversion, 0, 5.5), n(ttm_pa, 0, 4), n(openness, 0, 4), n(sitting_weekend, 0, 22), n(age, 0, 52), n(household_income, 0, 12), n(household_size, 0, 6)); } /** * @param v the value to be normalized. * @param min the min expected value * @param max the max expected value * @return normalized value of v: (v-min)/(max-min), or 0 if vmax. */ private static double n(double v, double min, double max) { if (min >= max) throw new IllegalArgumentException("min must be max) return 1; return (v - min) / (max - min); } @Override public String toString() { return Arrays.asList(godin_activity, exercise_se, exercise_identity, extraversion, ttm_pa, openness, sitting_weekend, age, household_income, household_size).toString(); } /** * * @param other another {@link Characteristics} * @return the Nele similarity to the other. Higher value means more * similar. The Nele similarity is based on the regression formula * reported by Nele. Note that the function is symmetrical: * distance(a,b) = distance(b,a). */ public double similarity(Characteristics other) { double dage = Math.abs(age - other.age); double dhousehold_income = Math .abs(household_income - other.household_income); double dhousehold_size = Math .abs(household_size - other.household_size); double dextraversion = Math.abs(extraversion - other.extraversion); double dopenness = Math.abs(openness - other.openness); double dttm = Math.abs(ttm_pa - other.ttm_pa); double dexerciseid = Math .abs(exercise_identity - other.exercise_identity); double dexercisese = Math.abs(exercise_se - other.exercise_se); double dsittingw = Math.abs(sitting_weekend - other.sitting_weekend); double dgodin = Math.abs(godin_activity - other.godin_activity); return 0.13887 - 0.64921 * dage + 0.76815 * dhousehold_income + 0.60581 * dhousehold_size - 0.73115 * dextraversion - 0.78798 * dopenness - 0.53480 * dttm - 0.44290 * dexerciseid - 0.82005 * dexercisese + 0.56707 * dsittingw - 0.88615 * dgodin; } private boolean notnormal(double val) { return val < 0 || val > 1; } @Override public int hashCode() { return Objects.hash(age, exercise_identity, exercise_se, extraversion, godin_activity, household_income, household_size, openness, sitting_weekend, ttm_pa); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Characteristics other = (Characteristics) obj; return Double.doubleToLongBits(age) == Double .doubleToLongBits(other.age) && Double.doubleToLongBits(exercise_identity) == Double .doubleToLongBits(other.exercise_identity) && Double.doubleToLongBits(exercise_se) == Double .doubleToLongBits(other.exercise_se) && Double.doubleToLongBits(extraversion) == Double .doubleToLongBits(other.extraversion) && Double.doubleToLongBits(godin_activity) == Double .doubleToLongBits(other.godin_activity) && Double.doubleToLongBits(household_income) == Double .doubleToLongBits(other.household_income) && Double.doubleToLongBits(household_size) == Double .doubleToLongBits(other.household_size) && Double.doubleToLongBits(openness) == Double .doubleToLongBits(other.openness) && Double.doubleToLongBits(sitting_weekend) == Double .doubleToLongBits(other.sitting_weekend) && Double.doubleToLongBits(ttm_pa) == Double .doubleToLongBits(other.ttm_pa); } }