RationalNumber operator ^ (const RationalNumber& B) const throw(std::invalid_argument) { if (!isFraction() || !B.isInteger()) { return RationalNumber(powl(getRealNumber(), B.getRealNumber())); } RationalNumber S(1, 1); RationalNumber A = *this; long long n = B.numerator; if (n < 0) { A = RationalNumber(1, 1) / A; n = -n; } while (n) { if (n & 1) { S = S * A; } A = A * A; n >>= 1; } return S; }
RationalNumber operator * (const RationalNumber& B) const { if (!isFraction() || !B.isFraction()) { return RationalNumber(getRealNumber() * B.getRealNumber()); } return RationalNumber(numerator * B.numerator, denominator * B.denominator); }
RationalNumber operator / (const RationalNumber& B) const throw(std::domain_error) { if (!isFraction() || !B.isFraction()) { return RationalNumber(getRealNumber() / B.getRealNumber()); } if (B.numerator == 0) { throw std::domain_error("Division by zero!"); } return RationalNumber(numerator * B.denominator, denominator * B.numerator); }
int rncCount(RationalNumberCollection *c, RationalNumber rn) { // Wenn rn ungültig -> return 0 if (!rnIsValid(rn)) { return 0; } // Länge der Collection bestimmen int len = rncTotalUniqueCount(*(&c)); // Wenn Collection leer ist -> return 0 if (len == 0) { return 0; } // Zeiger auf Collection RationalNumber (*ptr)[2] = c->rn; // rn kürzen rn = rnShorten(rn); // Falls Bruch bereits vorhanden, ermittel Vorkommen des Bruchs int i = rncSearch(*(&c), rn, 0, len-1); if (i >= 0) { return ptr[i][1].numerator; } return 0; }
int rncSearch(RationalNumberCollection *c, RationalNumber rn, int min, int max) { // Zeiger auf Collection RationalNumber (*ptr)[2] = c->rn; // Wenn Collection leer if (max < min) { return -1; } // Mitte der Collection ermitteln int mid = (min + max) / 2; // Wenn rn in der unteren Teil-Collection if (rnLessThan(rn,ptr[mid][0])) { return rncSearch(*(&c), rn, min, mid-1); } // Wenn rn in der oberen Teil-Collection else if (rnLessThan(ptr[mid][0],rn)) { return rncSearch(*(&c), rn, mid+1, max); } // rn wurde gefunden else { return mid; } }
void rncInit(RationalNumberCollection *c) { // Zeiger auf Collection RationalNumber (*ptr)[2] = c->rn; // Allen Arrayelementen eine RationalNumber mit Zähler- und Nennerwerten von 0 eintragen, // mit Ausnahme des Zähler-Denominators. Diese bekommen eine 1 spendiert, die für // Rechenoperationen nötig ist. RationalNumber rn = { 0, 0 }; RationalNumber counter = { 0, 1 }; for (int i=0; i<MAXSIZE; i++) { ptr[i][0] = rn; ptr[i][1] = counter; } // Setze totalUniqueCount auf 0 c->totalUniqueCount = 0; // Setze totalCount auf 0 c->totalCount = 0; // Setze sum auf 0/1 c->sum = counter; // Setze average auf 0/1 c->average = counter; // Setze median auf 0/1 c->median = counter; }
RationalNumber RationalNumber::subtract (const RationalNumber &other){ int commonDenominator = Denominator * other.getDenominator(); int numerator1 = Numerator * other.getDenominator(); int numerator2 = other.getNumerator() * Denominator; int difference = numerator1 - numerator2; return RationalNumber (difference, commonDenominator); }
RationalNumber RationalNumber::add(const RationalNumber &other){ int commonDenominator = Denominator * other.getDenominator(); int numerator1 = Numerator * other.getDenominator(); int numerator2 = other.getNumerator() * Denominator; int sum = numerator1 + numerator2; return RationalNumber (sum, commonDenominator); }
// call by value RationalNumber RationalNumber::operator-(const RationalNumber& other) const { if (other.isNaN()) return RationalNumber(*this); RationalNumber r(*this); r -= other; r.normalize(); return r; }
void rncAdd(RationalNumberCollection *c, RationalNumber rn) { // Wenn rn ungültig -> return if (!rnIsValid(rn)) { return; } // Länge der Collection ermitteln int len = rncTotalUniqueCount(*(&c)); // rn kürzen rn = rnShorten(rn); // Zeiger auf Collection RationalNumber (*ptr)[2] = c->rn; // Falls Bruch bereits vorhanden int i = rncSearch(*(&c), rn, 0, len-1); if (i >= 0) { // Erhöhe Counter des Bruchs ptr[i][1].numerator++; // Erhöhe totalCount der Collection c->totalCount++; // Erhöhe sum der Collection c->sum = rnShorten(rnAdd(c->sum,rn)); // Berechne average der Collection rncCalcAverage(*(&c)); return; } // Falls nocht nicht alle Elemente des Arrays belegt sind if (len < MAXSIZE) { // Trage den Bruch ein und erhöhe den Counter des Bruchs ptr[len][0] = rn; ptr[len][1].numerator++; // Erhöhe totalUniqueCount der Collection c->totalUniqueCount++; // Erhöhe totalCount der Collection c->totalCount++; // Erhöhe sum der Collection c->sum = rnShorten(rnAdd(c->sum,rn)); // Berechne average der Collection rncCalcAverage(*(&c)); } // Collection sortieren wenn Länge der Collection > 0 if (len > 0) { rncSort(*(&c), len+1); } // Berechne median der Collection rncCalcMedian(*(&c)); }
// call by value RationalNumber RationalNumber::operator+(const RationalNumber& other) const { if (other.isNaN()) return RationalNumber(*this); /* RationalNumber result(nomi() * other.deno() + other.nomi() * deno(), deno() * other.deno()); return result; */ RationalNumber r(*this); r += other; r.normalize(); return r; }
void rncRemove(RationalNumberCollection *c, RationalNumber rn) { // Wenn rn ungültig -> return if (!rnIsValid(rn)) { return; } // Länge der Collection ermitteln int len = rncTotalUniqueCount(*(&c)); // Wenn Collection leer -> return if (len == 0) { return; } // rn kürzen rn = rnShorten(rn); // Zeiger auf Collection RationalNumber (*ptr)[2] = c->rn; // Falls Bruch bereits vorhanden int i = rncSearch(*(&c), rn, 0, len-1); if (i >= 0) { // Veringere Counter des Bruchs ptr[i][1].numerator--; // Veringere totalCount der Collection c->totalCount--; // Verringere sum der Collection c->sum = rnShorten(rnSubtract(c->sum,rn)); // Wenn Counter anschließend == 0, entferne Bruch aus Collection if (ptr[i][1].numerator == 0) { ptr[i][0].numerator = 0; ptr[i][0].denominator = 0; // Verringere totalUniqueCount der Collection c->totalUniqueCount--; // Collection sortieren wenn Bruch nicht letzter Bruch in der Collection war if (len > 1) { rncSort(*(&c), len); } // Berechne median der Collection rncCalcMedian(*(&c)); } // Berechne average der Collection rncCalcAverage(*(&c)); } }
V3R SymmetryOperation::getReducedVector(const Kernel::IntMatrix &matrix, const V3R &vector) const { Kernel::IntMatrix translationMatrix(3, 3, false); for (size_t i = 0; i < order(); ++i) { Kernel::IntMatrix tempMatrix(3, 3, true); for (size_t j = 0; j < i; ++j) { tempMatrix *= matrix; } translationMatrix += tempMatrix; } return (translationMatrix * vector) * RationalNumber(1, static_cast<int>(order())); }
void rncCalcMedian(RationalNumberCollection *c) { // Länge der Collection bestimmen int len = rncTotalUniqueCount(*(&c)); // Wenn Collection leer if (len == 0) { RationalNumber result = { 0, 1 }; c->median = result; } // Zeiger auf Collection RationalNumber (*ptr)[2] = c->rn; // Wenn Länge der Collection == 1 if (len == 1) { c->median = ptr[0][0]; } // Wenn Länge der Collection == 2 if (len == 2) { RationalNumber r = { 2, 1 }; c->median = rnShorten(rnDivide(rnAdd(ptr[0][0], ptr[1][0]), r)); } // Wenn Länge der Collection gerade if (len%2 == 0) { RationalNumber r = { 2, 1 }; int lowerMedian = (len / 2) - 1; int upperMedian = len / 2; c->median = rnShorten(rnDivide(rnAdd(ptr[lowerMedian][0], ptr[upperMedian][0]), r)); } // Wenn Länge der Collection ungerade else { int median = len / 2; c->median = ptr[median][0]; } }
/// Determines the symbol from the translation vector using a map. std::string SymmetryElementMirrorGenerator::determineSymbol( const SymmetryOperation &operation) const { V3R rawTranslation = determineTranslation(operation); V3R translation; for (size_t i = 0; i < 3; ++i) { translation[i] = rawTranslation[i] > RationalNumber(1, 2) ? rawTranslation[i] - 1 : rawTranslation[i]; } std::string symbol = g_glideSymbolMap[translation.getPositiveVector()]; /* Some space groups have "unconventional glides" for which there is no * proper symbol, so the general symbol "g" is used for these cases. * Examples can be found in No. 227 (Fd-3m). */ if (symbol == "") { return "g"; } return symbol; }
void rncCalcAverage(RationalNumberCollection *c) { // Zeiger auf Collection RationalNumber (*ptr)[2] = c->rn; // Alle Brüche in der Collection zählen und sie summieren int i = 0; RationalNumber count = { 0, 1 }; RationalNumber result = { 0, 1 }; while(ptr[i][1].numerator > 0) { result = rnAdd(result, rnMultiply(ptr[i][0], ptr[i][1])); count.numerator += ptr[i][1].numerator; i++; } // Wenn keine Brüche gespeichert if (count.numerator == 0) { count.numerator = 1; } // Gekürzte RationalNumber zurückgeben c->average = rnShorten(rnDivide(result, count)); }
//return the quotient of this and a RationalNumber RationalNumber::operator/(RationalNumber a) { return RationalNumber(numerator * a.denominator, denominator * a.numerator); }
//returns the difference of this and a RationalNumber RationalNumber::operator-(RationalNumber a) { int num = numerator * a.denominator - a.numerator * denominator; int denom = a.denominator * denominator; return RationalNumber(num, denom); }
//definition for overload method operator / RationalNumber RationalNumber::operator/(RationalNumber rn) { return RationalNumber(numerator*rn.denominator, denominator*rn.numerator); }
RationalNumber RationalNumber:: reciprocal(){ return RationalNumber(Denominator, Numerator); }
RationalNumber RationalNumber::multiply(const RationalNumber &other){ int numer = Numerator * other.getNumerator(); int denom = Denominator * other.getDenominator(); return RationalNumber (numer, denom); }
void rncSort(RationalNumberCollection *c, int len) { // Temporäre Collection erstellen RationalNumberCollection temp; rncInit(&temp); // Zeiger auf Collection RationalNumber (*ptr)[2] = c->rn; // Zeiger auf temporäre Collection RationalNumber (*tempptr)[2] = temp.rn; // Variablen zum Speichern von Indexpositionen int tempIndex = 0; int minIndex = 0; // Solange sich Brüche in der Collection c befinden while (minIndex != -1) { minIndex = -1; // Suche kleinsten Bruch aus der Collection c int minCount; for (int i=0; i<len; i++) { if (ptr[i][1].numerator == 0) { continue; } if (minIndex == -1 || rnLessThan(ptr[i][0],ptr[minIndex][0])) { minIndex = i; minCount = ptr[i][1].numerator; } } // Wenn kleinsten Bruch gefunden if (minIndex != -1) { // Übertrage den gefunden kleinsten Bruch und dessen Vorkommen in die Collection temp tempptr[tempIndex][0] = ptr[minIndex][0]; tempptr[tempIndex][1].numerator = minCount; // Erhöhe den totalUniqueCount der Collection temp temp.totalUniqueCount++; // Entferne den gefunden kleinsten Bruch und dessen Vorkommen aus der Collection c ptr[minIndex][0].numerator = 0; ptr[minIndex][0].denominator = 0; ptr[minIndex][1].numerator = 0; // Zeige auf den nächsten Index der Collection temp tempIndex++; } } // Übertrage alle Brüche und ihre Vorkommen der Collection temp in die Collection c int tempLen = rncTotalUniqueCount(&temp); for (int j=0; j<tempLen; j++) { ptr[j][0] = tempptr[j][0]; ptr[j][1].numerator = tempptr[j][1].numerator; } }