/* --------------------------------------------------------------------- * Numenta Platform for Intelligent Computing (NuPIC) * Copyright (C) 2014, Numenta, Inc. Unless you have an agreement * with Numenta, Inc., for a separate license for this software code, the * following terms and conditions apply: * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero Public License for more details. * * You should have received a copy of the GNU Affero Public License * along with this program. If not, see http://www.gnu.org/licenses. * * http://numenta.org/licenses/ * --------------------------------------------------------------------- */ package org.numenta.nupic.monitor.mixin; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import org.numenta.nupic.model.Connections; import org.numenta.nupic.monitor.MonitoredTemporalMemory; import com.bethecoder.table.AsciiTableInstance; import com.bethecoder.table.spec.AsciiTable; /** * Base class for MonitorMixin. Each subclass will be a mixin for a particular * algorithm. * * All arguments, variables, and methods in monitor mixin classes should be * prefixed with "mm" (to avoid collision with the classes they mix in to). * * To make a "Mixin": * <OL> * <li>Create a Decorator interface (A) containing overridden methods</li> * <li>Create MonitorMixinBase extension mixin type (interface) (this does most of the mixin work) see {@link TemporalMemoryMonitorMixin}</li> * <li>Create Extension of both {@link MonitorMixinBase} and interface (see {@link MonitoredTemporalMemory})</li> * <li>Create constructor in extension class which takes above interface (A) which is the target class which must implement (A)</li> * <li>Make the Original class (see {@link TemporalMemory}) to be tested, implement the Decorator interface (A)</li> * <li>Use the "joining" extension class as you would the original class</li> * </OL> * * * @author David Ray */ public interface MonitorMixinBase { public <T> T getMonitor(); public Connections getConnections(); public Map<String, Trace<?>> getTraceMap(); public Map<String, Map<String, ?>> getDataMap(); public String mmGetName(); public void mmClearHistory(); public <T extends Trace<?>> List<T> mmGetDefaultTraces(int verbosity); public List<Metric> mmGetDefaultMetrics(int verbosity); default String mmPrettyPrintTraces(List<Trace<?>> traces, BoolsTrace breakOnResets) { String[] header = new String[traces.size() + 1]; header[0] = "#"; for(int i = 0;i < traces.size();i++) header[i + 1] = traces.get(i).prettyPrintTitle(); int len = traces.get(0).items.size(); List<String[]> table = new ArrayList<>(len); for(int i = 0;i < len;i++) { if(breakOnResets != null && breakOnResets.items.get(i)) { table.add(Collections.nCopies(header.length + 1, "<reset>").toArray(new String[header.length + 1])); } String[] sa = new String[traces.size() + 1]; sa[0] = "" + i; int x = 1; for(Trace<?> t : traces) { sa[x++] = t.prettyPrintDatum(t.items.get(i)); } table.add(sa); } String retVal = AsciiTableInstance.get().getTable(header, table.toArray(new String[table.size()][]), AsciiTable.ALIGN_CENTER); return retVal; } default String mmPrettyPrintMetrics(List<Metric> metrics, int sigFigs) { String hashes = ""; for(int i = 0;i < Math.max(2, sigFigs);i++) { hashes += "#"; } DecimalFormat df = new DecimalFormat("0." + hashes); String[] header = new String[] { "Metric", "mean", "standard deviation", "min", "max", "sum" }; String[][] data = new String[metrics.size()][header.length]; int i = 0; for(Metric metric : metrics) { for(int j = 0;j < header.length;j++) { if(j == 0) { data[i][j] = metric.prettyPrintTitle(); }else{ double[] stats = metric.getStats(sigFigs); data[i][j] = ((int)stats[j - 1]) == stats[j - 1] ? df.format(stats[j - 1]) + ".0" : df.format(stats[j - 1]); } } i++; } String retVal = AsciiTableInstance.get().getTable(header, data, AsciiTable.ALIGN_CENTER); return retVal; } }