📄 distvars.cpp
字号:
/*
This file is part of Orange.
Orange is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Orange 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with Orange; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Authors: Janez Demsar, Blaz Zupan, 1996--2002
Contact: janez.demsar@fri.uni-lj.si
*/
#include <math.h>
#include "crc.h"
#include "stat.hpp"
#include "random.hpp"
#include "values.hpp"
#include "vars.hpp"
#include "stladdon.hpp"
#include "domain.hpp"
#include "examplegen.hpp"
#include "examples.hpp"
#include "distvars.ppp"
DEFINE_TOrangeVector_classDescription(PDistribution, "TDistributionList", true, ORANGE_API)
#define CHECKVALTYPE(valType) \
if (! ( (valType==TValue::INTVAR) && supportsDiscrete \
|| (valType==TValue::FLOATVAR) && supportsContinuous)) \
raiseError("invalid value type");
#define NOT_IMPLEMENTED(x) { raiseError("'%s' is not implemented", x); throw 0; /*just to avoid warnings*/ }
TDistribution::TDistribution()
: unknowns(0.0),
abs(0.0),
cases(0.0),
normalized(false),
supportsDiscrete(false),
supportsContinuous(false)
{}
TDistribution::TDistribution(PVariable var)
: variable(var),
unknowns(0.0),
abs(0.0),
cases(0.0),
normalized(false),
supportsDiscrete(false),
supportsContinuous(false)
{}
TDistribution *TDistribution::create(PVariable var)
{ if (!var)
return NULL;
if (var->varType==TValue::INTVAR)
return mlnew TDiscDistribution(var);
if (var->varType==TValue::FLOATVAR)
return mlnew TContDistribution(var);
::raiseErrorWho("Distribution", "unknown value type");
return NULL; // to make compiler happy
}
TDistribution *TDistribution::fromGenerator(PExampleGenerator gen, const int &position, const int &weightID)
{
if (position >= gen->domain->variables->size())
::raiseErrorWho("Distribution", "index %i out of range", position);
PVariable var = gen->domain->variables->at(position);
if (var->varType == TValue::INTVAR)
return mlnew TDiscDistribution(gen, position, weightID);
if (var->varType == TValue::FLOATVAR)
return mlnew TContDistribution(gen, position, weightID);
::raiseErrorWho("Distribution", "unknown value type");
return NULL; // to make compiler happy
}
TDistribution *TDistribution::fromGenerator(PExampleGenerator gen, PVariable var, const int &weightID)
{
if (var->varType == TValue::INTVAR)
return mlnew TDiscDistribution(gen, var, weightID);
if (var->varType == TValue::FLOATVAR)
return mlnew TContDistribution(gen, var, weightID);
::raiseErrorWho("Distribution", "unknown value type");
return NULL; // to make compiler happy
}
// General
float TDistribution::compatibility(const TSomeValue &) const
NOT_IMPLEMENTED("compatibility")
bool TDistribution::compatible(const TSomeValue &) const
NOT_IMPLEMENTED("compatible")
int TDistribution::compare(const TSomeValue &) const
NOT_IMPLEMENTED("compare")
TDistribution &TDistribution::operator += (const TDistribution &)
NOT_IMPLEMENTED("+=")
TDistribution &TDistribution::operator -= (const TDistribution &)
NOT_IMPLEMENTED("-=")
TDistribution &TDistribution::operator *= (const TDistribution &)
NOT_IMPLEMENTED("*=")
TDistribution &TDistribution::operator *= (const float &)
NOT_IMPLEMENTED("*=")
// Discrete
const float &TDistribution::atint(const int &)
NOT_IMPLEMENTED("atint(int)")
const float &TDistribution::atint(const int &) const
NOT_IMPLEMENTED("atint(int)")
void TDistribution::addint(const int &, const float &)
NOT_IMPLEMENTED("addint(int, float)")
void TDistribution::setint(const int &, const float &)
NOT_IMPLEMENTED("add(int, float)")
int TDistribution::randomInt()
NOT_IMPLEMENTED("randomInt()")
int TDistribution::randomInt(const long &)
NOT_IMPLEMENTED("randomInt(long)")
int TDistribution::highestProbIntIndex() const
NOT_IMPLEMENTED("highestProbIntIndex()")
int TDistribution::highestProbIntIndex(const long &) const
NOT_IMPLEMENTED("highestProbIntIndex(int)")
int TDistribution::highestProbIntIndex(const TExample &) const
NOT_IMPLEMENTED("highestProbIntIndex(TExample)")
float TDistribution::p(const int &) const
NOT_IMPLEMENTED("p(int)")
int TDistribution::noOfElements() const
NOT_IMPLEMENTED("noOfElements()")
// Continuous
const float &TDistribution::atfloat(const float &)
NOT_IMPLEMENTED("atfloat(float)")
const float &TDistribution::atfloat(const float &) const
NOT_IMPLEMENTED("atfloat(float)")
void TDistribution::addfloat(const float &, const float &)
NOT_IMPLEMENTED("addfloat(float, float)")
void TDistribution::setfloat(const float &, const float &)
NOT_IMPLEMENTED("add(float, float)")
float TDistribution::randomFloat()
NOT_IMPLEMENTED("randomFloat()")
float TDistribution::randomFloat(const long &)
NOT_IMPLEMENTED("randomFloat(long)")
float TDistribution::highestProbFloatIndex() const
NOT_IMPLEMENTED("highestProbFloatIndex()")
float TDistribution::average() const
NOT_IMPLEMENTED("average()")
float TDistribution::dev() const
NOT_IMPLEMENTED("dev()")
float TDistribution::var() const
NOT_IMPLEMENTED("dev()")
float TDistribution::error() const
NOT_IMPLEMENTED("error()")
float TDistribution::percentile(const float &) const
NOT_IMPLEMENTED("percentile(float)")
float TDistribution::p(const float &) const
NOT_IMPLEMENTED("p(float)")
TDistribution &TDistribution::operator +=(PDistribution other)
{ return operator += (other.getReference()); }
TDistribution &TDistribution::operator -=(PDistribution other)
{ return operator -= (other.getReference()); }
TDistribution &TDistribution::operator *=(PDistribution other)
{ return operator *= (other.getReference()); }
float TDistribution::operator - (const TSomeValue &v) const
{ return 1-compatibility(v); }
float TDistribution::operator || (const TSomeValue &v) const
{ return 1-compatibility(v); }
const float &TDistribution::operator[](const TValue &val) const
{ if (val.isSpecial()) {
if (variable)
raiseError("undefined value of attribute '%s'", variable->name.c_str());
else
raiseError("undefined attribute value");
}
CHECKVALTYPE(val.varType);
return (val.varType==TValue::INTVAR) ? atint(int(val)) : atfloat(float(val));
}
const float &TDistribution::operator[](const TValue &val)
{ if (val.isSpecial()) {
if (variable)
raiseError("undefined value of attribute '%s'", variable->name.c_str());
else
raiseError("undefined attribute value");
}
CHECKVALTYPE(val.varType);
return (val.varType==TValue::INTVAR) ? atint(int(val)) : atfloat(float(val));
}
void TDistribution::add(const TValue &val, const float &p)
{
if (!val.svalV || !variable || !variable->distributed) {
if (val.isSpecial()) {
unknowns += p;
if (!val.svalV || !val.svalV.is_derived_from(TDistribution))
return;
}
else {
CHECKVALTYPE(val.varType);
if (val.varType==TValue::INTVAR)
addint(val.intV, p);
else
addfloat(val.floatV, p);
return;
}
}
if (!val.svalV)
unknowns += p;
const TDiscDistribution *ddist = val.svalV.AS(TDiscDistribution);
if (ddist) {
if (!supportsDiscrete || variable && ddist->variable && (variable!=ddist->variable))
raiseError("invalid value type");
int i = 0;
const_PITERATE(TDiscDistribution, ddi, ddist)
addint(i++, *ddi*p);
return;
}
const TContDistribution *cdist = val.svalV.AS(TContDistribution);
if (cdist) {
if (!supportsContinuous || variable && ddist->variable && (variable!=ddist->variable))
raiseError("invalid value type");
const_PITERATE(TContDistribution, cdi, cdist)
addfloat((*cdi).first, (*cdi).second*p);
return;
}
raiseError("invalid value type");
}
void TDistribution::set(const TValue &val, const float &p)
{ if (!val.isSpecial()) {
CHECKVALTYPE(val.varType);
if (val.varType==TValue::INTVAR)
setint(val.intV, p);
else
setfloat(val.floatV, p);
}
}
TValue TDistribution::highestProbValue() const
{ if (supportsDiscrete)
return TValue(highestProbIntIndex());
else if (supportsContinuous)
return TValue(highestProbFloatIndex());
else
return TValue();
}
TValue TDistribution::highestProbValue(const long &random) const
{ if (supportsDiscrete)
return TValue(highestProbIntIndex(random));
else if (supportsContinuous)
return TValue(highestProbFloatIndex());
else
return TValue();
}
TValue TDistribution::highestProbValue(const TExample &exam) const
{ if (supportsDiscrete)
return TValue(highestProbIntIndex(exam));
else if (supportsContinuous)
return TValue(highestProbFloatIndex());
else
return TValue();
}
TValue TDistribution::randomValue()
{ if (supportsDiscrete)
return TValue(randomInt());
else if (supportsContinuous)
return TValue(randomFloat());
else
return TValue();
}
TValue TDistribution::randomValue(const long &random)
{ if (supportsDiscrete)
return TValue(randomInt(random));
else if (supportsContinuous)
return TValue(randomFloat(random));
else
return TValue();
}
float TDistribution::p(const TValue &val) const
{ if (val.isSpecial()) {
if (variable)
raiseError("undefined value of attribute '%s'", variable->name.c_str());
else
raiseError("undefined attribute value");
}
CHECKVALTYPE(val.varType);
return (val.varType==TValue::INTVAR) ? p(int(val)) : p(float(val));
}
TDiscDistribution::TDiscDistribution()
{ supportsDiscrete = true; };
TDiscDistribution::TDiscDistribution(PVariable var)
: TDistribution(var)
{ if (var->varType!=TValue::INTVAR)
raiseError("attribute '%s' is not discrete", var->name.c_str());
distribution = vector<float>(var->noOfValues(), 0.0);
supportsDiscrete = true;
}
TDiscDistribution::TDiscDistribution(int values, float value)
: distribution(vector<float>(values, value))
{ cases = abs = value*values;
supportsDiscrete = true;
}
TDiscDistribution::TDiscDistribution(const vector<float> &f)
: distribution(f)
{ abs = 0.0;
for (const_iterator fi(begin()), fe(end()); fi!=fe; abs += *(fi++));
cases = abs;
supportsDiscrete = true;
}
TDiscDistribution::TDiscDistribution(const float *f, const int &len)
: distribution(f, f+len)
{ abs = 0.0;
for (const_iterator fi(begin()), fe(end()); fi!=fe; abs += *(fi++));
cases = abs;
supportsDiscrete = true;
}
TDiscDistribution::TDiscDistribution(PDistribution other)
: TDistribution(other.getReference())
{ supportsDiscrete = true; }
TDiscDistribution::TDiscDistribution(PDiscDistribution other)
: TDistribution(other.getReference())
{ supportsDiscrete = true; }
TDiscDistribution::TDiscDistribution(PExampleGenerator gen, const int &position, const int &weightID)
{
supportsDiscrete = true;
if (position >= gen->domain->variables->size())
raiseError("index %i out of range", position);
variable = gen->domain->variables->at(position);
if (variable->varType != TValue::INTVAR)
raiseError("attribute '%s' is not discrete", variable->name.c_str());
distribution = vector<float>(variable->noOfValues(), 0.0);
PEITERATE(ei, gen)
add((*ei)[position], WEIGHT(*ei));
}
TDiscDistribution::TDiscDistribution(PExampleGenerator gen, PVariable var, const int &weightID)
: TDistribution(var)
{
supportsDiscrete = true;
if (variable->varType != TValue::INTVAR)
raiseError("attribute '%s' is not discrete", variable->name.c_str());
distribution = vector<float>(var->noOfValues(), 0.0);
int position = gen->domain->getVarNum(variable, false);
if (position != ILLEGAL_INT)
PEITERATE(ei, gen)
add((*ei)[position], WEIGHT(*ei));
else
if (variable->getValueFrom)
PEITERATE(ei, gen)
add(variable->computeValue(*ei), WEIGHT(*ei));
else
raiseError("attribute '%s' not in domain and cannot be computed", variable->name.c_str());
}
const float &TDiscDistribution::atint(const int &v)
{ int ms = v + 1 - size();
if (ms>0) {
reserve(v+1);
while (ms--)
push_back(0.0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -