mpf CosineCalculator::singleThreadedCosine() { mpf cos(0, exponent); mpf aux(0, exponent); unsigned int singleIterations = 0; while (true) { aux = std::move(calculateTerm(radians, singleIterations)); cos = cos + aux; singleIterations++; if (abs(aux) < precision) break; gmp_printf("Partial cosine value: %.*Ff\n", exponent, cos.get_mpf_t()); } gmp_printf("Final cosine value: %.*Ff\n", exponent, cos.get_mpf_t()); std::cout << "Number of different calculated terms: " << singleIterations << std::endl; return cos; }
eS32 readValInstanciation(const eString& s, int start, int end, eU32* parMap, eF32* params, const eF32* prevParams) { int pos = start; int v = 0; if((pos >= end) || (s.at(pos) != '(')) { return pos; } else { pos++; while((pos < end) && (s.at(pos) != ')')) { if(s.at(pos) == ',') { pos++; continue; } pos = calculateTerm(s, pos, end, parMap, prevParams, params[v++]); eASSERT(pos != -1); } } return pos + 1; }
void CosineCalculator::worker(unsigned int offset) { terms[offset] = std::move(calculateTerm(radians, iteration * terms.size() + offset)); if (operation_mode == 'd') std::cout << "Thread number " << offset << " has reached the barrier!" << std::endl; }
// calculates the expression in the string // returns the position after second number eS32 calculateTerm(const eString& s, int start, int end, const eU32* parMap, const eF32* params, eF32& result) { int pos = start; eF32 tuple[] = {0,0}; eU32 tpos = 0; eU32 op = 0; eU32 c; while((pos < end) && ((c = s.at(pos)) != ',') && (c != ')')) { if(c == '(') { pos = calculateTerm(s, pos + 1, end, parMap, params, tuple[tpos]); eASSERT(pos != -1); pos++; } else { eS32 oldPos = pos; // try to read constant eF32 number = 0; eF32 v = 1.0f; while(pos < end) { int cc = s.at(pos) - '0'; if(cc == '.' - '0') v = 0.1f; else if((eU32)cc <= 9) {// is a number if(v >= 1.0f) number = number * 10.0f + cc; else { number += v * cc; v /= 10.0f; } tuple[tpos] = number; } else break; pos++; } // try to read symbol eASSERT(parMap != eNULL); for(eU32 i = 0; i < LSYS_PAR_MAX; i++) if(parMap[i] == c) { tuple[tpos] = params[i]; pos++; } if(pos == oldPos) { // is an operator pos++; op = c; tpos++; }; } } switch(op) { case '+': result = tuple[0] + tuple[1]; break; case '-': result = tuple[0] - tuple[1]; break; case '*': result = tuple[0] * tuple[1]; break; case '/': result = tuple[0] / tuple[1]; break; case '<': result = (tuple[0] < tuple[1]) ? 1.0f : 0.0f; break; case '=': result = (tuple[0] == tuple[1]) ? 1.0f : 0.0f; break; case '>': result = (tuple[0] > tuple[1]) ? 1.0f : 0.0f; break; case '^': result = ePow(tuple[0], tuple[1]); break; default: result = tuple[0]; // single term } return pos; }
void eLSystem::evaluate(const tState& baseState) { this->numProductions = 1; ePROFILER_ZONE("L-System - Evaluate"); // interpret product eU32 initialStackpos = stackPos; this->reset(); // now we can start derivating for(eU32 it = 0; it < m_iterations; it++) { tState sstate = baseState; tState *state = &sstate; state->scopeStart = 0; eArray<tSymbol>& curProduction = this->productions[numProductions - 1]; eArray<tSymbol>& nextProduction = this->productions[numProductions++]; nextProduction.clear(); int ppos = 0; while(ppos < (eS32)curProduction.size()) { const tSymbol& curSymbol = curProduction[ppos]; eS32 symbolRaw = curSymbol.symbol; eBool isVariable = (symbolRaw >= LSYS_VAR_MIN) && (symbolRaw <= LSYS_VAR_MAX); state->turtle.rotation = state->curBaseRotation * curSymbol.rotation; state->turtle.texAngle = curSymbol.texVecAngle; if(symbolRaw == '[') this->pushState(&state); if(symbolRaw == ']') this->popState(&state); ////////////////////////////// /// Calculate next product /// ////////////////////////////// // initialize next tSymbol& nextSymbol = nextProduction.push(curSymbol); nextSymbol.rotation = state->turtle.rotation; nextSymbol.texVecAngle = state->turtle.texAngle; eSinCos(state->turtle.texAngle, nextSymbol.texVec.x, nextSymbol.texVec.y); // nextSymbol.texVec = eVector2(eSin(state->turtle.texAngle), eCos(state->turtle.texAngle)); nextSymbol.parentIdx = ppos; nextSymbol.scopeStartIdx = state->scopeStart; // TODO: reenable parameter copy //for(int i = 0; i < LSYS_MAX_SYMBOLS; i++) // nextParam[nextProdLen * LSYS_MAX_SYMBOLS + i] = param[ppos * LSYS_MAX_SYMBOLS + i]; if(symbolRaw == '[') { this->pushState(&state); state->scopeStart = nextProduction.size() - 1; } else if(symbolRaw == ']') { this->popState(&state); } else /*if(isVariable)*/ { int rpos[LSYS_MAX_RULES]; eU32 ruleNr[LSYS_MAX_RULES]; eU32 numRules = 0; // iterate through rules and lookup those with matching boolean conditions for(eU32 i = 0; i < symRules[symbolRaw].size(); i++) { ruleNr[i] = symRules[symbolRaw][i]; rpos[numRules] = ruleOffsets[ruleNr[i]]; // read boolean expression eF32 ruleCondition = 1.0f; if(this->grammar.at(rpos[numRules]) == '(') { rpos[numRules] = 1 + calculateTerm(this->grammar, rpos[numRules] + 1, this->grammar.length(), ¶mTable[ruleNr[i]][0], &curSymbol.params[0], ruleCondition); eASSERT(rpos[numRules] != 0); } if(ruleCondition != 0) { // rule can be applied eASSERT(rpos[numRules] != 0); numRules++; } } if(numRules != 0) { nextProduction.removeLastElement(); // pick rule at random eU32 i = eRandom(0, numRules); eASSERT(rpos[i] >= 0); // take this rule while(rpos[i] < (eS32)this->grammar.length()) { // read symbol int nsym = this->grammar.at(rpos[i]++); if(nsym == ';') break; eF32 sparams[LSYS_PAR_MAX]; if(this->grammar.at(rpos[i]) == '(') rpos[i] = readValInstanciation(this->grammar, rpos[i], this->grammar.length(), ¶mTable[ruleNr[i]][0], &sparams[0], &curSymbol.params[0]); else this->setDefaultParams(nsym, &sparams[0], &curSymbol.params[0]); // eVector3 rotateAxis; eF32 rotateAmount = 0.0f; eU32 rotateAxis; switch(nsym) { case '|': rotateAxis = 0; rotateAmount = ePI; break; case '+': rotateAxis = 0; rotateAmount = -sparams[0]; state->turtle.texAngle -= sparams[0]; break; case '-': rotateAxis = 0; rotateAmount = sparams[0]; state->turtle.texAngle += sparams[0]; break; case '<': rotateAxis = 1; rotateAmount = -sparams[0]; break; case '>': rotateAxis = 1; rotateAmount = sparams[0]; break; case '\\': rotateAxis = 2; rotateAmount = -sparams[0]; break; case '/': rotateAxis = 2; rotateAmount = sparams[0]; break; #ifdef eEDITOR case '$': // roll to horizontal left axis eShowError("Temporarily disabled"); break; #endif /* case '$': // roll to horizontal left axis { eVector3 look = state->turtle.rotation.getVector(2); eVector3 curLeft = state->turtle.rotation.getVector(0); eVector3 targetLeft = (eVector3(0,1,0) ^ look).normalized(); eF32 cosAngle = eClamp(-1.0f, curLeft * targetLeft, 1.0f); eF32 angle = eACos(cosAngle); rotateAxis = look; rotateAmount = angle; break; } */ default: // ePROFILER_ZONE("L-System - Evaluate Expand"); tSymbol& nextSymbol = nextProduction.push(tSymbol()); nextSymbol.symbol = nsym; for(eU32 p = 0; p < LSYS_PAR_MAX; p++) nextSymbol.params[p] = sparams[p]; nextSymbol.parentIdx = ppos; nextSymbol.scopeStartIdx = state->scopeStart; nextSymbol.rotation = state->turtle.rotation; nextSymbol.mass = (state->turtle.size * state->turtle.height) * (state->turtle.size * state->turtle.width); nextSymbol.texVecAngle = state->turtle.texAngle; eSinCos(state->turtle.texAngle, nextSymbol.texVec.x, nextSymbol.texVec.y); // nextSymbol.texVec = eVector2(eSin(state->turtle.texAngle), eCos(state->turtle.texAngle)); if(nsym == '[') { this->pushState(&state); state->scopeStart = nextProduction.size() - 1; } else if(nsym == ']') { this->popState(&state); } // propagate mass to parent symbols if((nsym >= LSYS_VAR_MIN) && (nsym <= LSYS_VAR_MAX)) { // ePROFILER_ZONE("L-System - Propagate Mass"); eU32 subCnt = 0; for(int i = nextProduction.size() - 2; i >= 0; i--) { if(nextProduction[i].symbol == ']') i = nextProduction[i].scopeStartIdx; else { // add mass nextProduction[i].mass += nextSymbol.mass; } } } } if(rotateAmount != 0.0f) { state->curBaseRotation = eQuat(state->turtle.rotation.getVector(rotateAxis), rotateAmount) * state->curBaseRotation; state->turtle.rotation = state->curBaseRotation * curSymbol.rotation; } } } } ppos++; } } eASSERT(stackPos==initialStackpos); }