void MMO_Expression_::_traverseAlgebraics (Dependencies deps, Index derivativeIndex, Dependencies derivativeDeps, map<Index, Index> *states, map<Index, Index> *discretes, Index variableChange, DEP_Type type, int value) { for (Index *idx = deps->begin (type); !deps->end (type); idx = deps->next (type)) { list<MMO_Equation> algEqs = _data->algebraics ()->equation (*idx); list<MMO_Equation>::iterator algEq; if (type == DEP_ALGEBRAIC_VECTOR_DEF) { derivativeDeps->insert (*idx, DEP_ALGEBRAIC_VECTOR); } int algValue = -1; for (algEq = algEqs.begin (); algEq != algEqs.end (); algEq++) { Index algebraicIdx = *idx; if (value >= 0 && idx->hasRange ()) { algebraicIdx = idx->indexValue (value); } if (!(*algEq)->exp()->deps()->autonomous()) { _deps->setAutonomous(false); } Index variableCh; int f = (*algEq)->lhs ().factor (); int c = (*algEq)->lhs ().operConstant (); if (f != 0 && type == DEP_ALGEBRAIC_DEF) { if (f != 1 || c != 0) { variableCh.setFactor (f); variableCh.setConstant (-c); variableCh.setLow ((*algEq)->lhs ().low () * f + c); variableCh.setHi ((*algEq)->lhs ().hi () * f + c); } } Index algebraicIndex = (*algEq)->lhs (); if (variableChange.isSet ()) { algebraicIndex = (*algEq)->lhs ().applyVariableChange ( variableChange); algebraicIdx = idx->applyVariableChange (variableChange); algebraicIdx.setLow (variableChange.low ()); algebraicIdx.setHi (variableChange.hi ()); } Intersection is = algebraicIndex.intersection (algebraicIdx); if (is.type () != IDX_DISJOINT) { Index algKey = algebraicIdx; Index equationIndex; equationIndex.setOffset (_equationIndex++); if (is.hasRange ()) { equationIndex.setRange (); equationIndex.setLow (is.low ()); equationIndex.setHi (is.hi ()); algKey.setRange (); algKey.setHi (equationIndex.hi ()); algKey.setLow (equationIndex.low ()); } else { equationIndex.setConstant (is.modelicaValue ()); if (is.type () == IDX_CONSTANT_BA) { algKey.setConstant (is.modelicaValue () + is.begin ()); algValue = is.modelicaValue (); } else if (is.type () == IDX_CONSTANT_AB) { algKey.setConstant (is.modelicaValue () + is.begin ()); algValue = is.modelicaValue (); } else { algKey.setConstant (is.modelicaValue ()); } algKey.setLow (1); algKey.setHi (1); algKey.setFactor (0); } if (type == DEP_ALGEBRAIC_DEF) { derivativeDeps->insert (algKey, DEP_ALGEBRAIC); } _addAlgebriacDeps (algKey, (*algEq), equationIndex, derivativeIndex, derivativeDeps, states, discretes, variableCh, algValue); } } } }
void MMO_Expression_::_addAlgebriacDeps (Index algIndex, MMO_Equation equation, Index equationIndex, Index derivativeIndex, Dependencies derivativeDeps, map<Index, Index> *states, map<Index, Index> *discretes, Index variableChange, int value) { stringstream buffer; string indent; string variableString = equation->lhs ().variable (algIndex, "i"); Dependencies deps = equation->exp ()->deps (); map<Index, Index> &stateVariables = *states; Index eqIndex = equationIndex; for (Index *idx = deps->begin (DEP_STATE); !deps->end (DEP_STATE); idx = deps->next (DEP_STATE)) { if (stateVariables.find (*idx) == stateVariables.end () || equation->lhs ().variableChange (algIndex)) { Index stateIndex = Index ( idx->applyVariableChange ( equation->lhs ().variableIndex (algIndex))); stateVariables[*idx] = *idx; eqIndex.setOffset (_equationIndex++); if (idx->hasRange () && eqIndex.hasRange ()) { // X[i] = B[i]; derivativeDeps->insert (stateIndex, eqIndex, DEP_ALGEBRAIC_STATE); } else if (!idx->hasRange () && eqIndex.hasRange ()) { // X[i] = B[N]; derivativeDeps->insert (stateIndex, eqIndex, DEP_ALGEBRAIC_STATE); } else if (idx->hasRange () && !eqIndex.hasRange ()) { // X[N] = B[i]; if (derivativeIndex.hasRange ()) { Index newEqIndex = eqIndex; newEqIndex.setRange (); newEqIndex.setLow (derivativeIndex.low ()); newEqIndex.setHi (derivativeIndex.hi ()); derivativeDeps->insert ( stateIndex.indexValue ( stateIndex.value (algIndex.constant ())), newEqIndex, DEP_ALGEBRAIC_STATE); } else { derivativeDeps->insert ( stateIndex.indexValue ( stateIndex.value (algIndex.constant ())), eqIndex, DEP_ALGEBRAIC_STATE); } } else if (!idx->hasRange () && !eqIndex.hasRange ()) { // X[N] = B[N]; if (derivativeIndex.hasRange () && !algIndex.isArray()) { Index newEqIndex = eqIndex; newEqIndex.setRange (); newEqIndex.setLow (derivativeIndex.low ()); newEqIndex.setHi (derivativeIndex.hi ()); derivativeDeps->insert (stateIndex, newEqIndex, DEP_ALGEBRAIC_STATE); } else { derivativeDeps->insert (stateIndex, eqIndex, DEP_ALGEBRAIC_STATE); } } } } map<Index, Index> &discreteVariables = *discretes; for (Index *idx = deps->begin (DEP_DISCRETE); !deps->end (DEP_DISCRETE); idx = deps->next (DEP_DISCRETE)) { if (discreteVariables.find (*idx) == discreteVariables.end () || equation->lhs ().variableChange (algIndex)) { Index discreteIndex = Index ( idx->applyVariableChange ( equation->lhs ().variableIndex (algIndex))); discreteVariables[*idx] = *idx; eqIndex.setOffset (_equationIndex++); if (idx->hasRange () && eqIndex.hasRange ()) { // X[i] = B[i]; derivativeDeps->insert (discreteIndex, eqIndex, DEP_ALGEBRAIC_DISCRETE); } else if (!idx->hasRange () && eqIndex.hasRange ()) { // X[i] = B[N]; derivativeDeps->insert (discreteIndex, eqIndex, DEP_ALGEBRAIC_DISCRETE); } else if (idx->hasRange () && !eqIndex.hasRange ()) { // X[N] = B[i]; derivativeDeps->insert ( discreteIndex.indexValue ( discreteIndex.value (discreteIndex.constant ())), eqIndex, DEP_ALGEBRAIC_DISCRETE); } else if (!idx->hasRange () && !eqIndex.hasRange ()) { // X[N] = B[N]; derivativeDeps->insert (discreteIndex, eqIndex, DEP_ALGEBRAIC_DISCRETE); } } } for (Index *idx = deps->begin (DEP_STATE_VECTOR); !deps->end (DEP_STATE_VECTOR); idx = deps->next (DEP_STATE_VECTOR)) { derivativeDeps->insert (*idx, DEP_STATE_VECTOR); } for (Index *idx = deps->begin (DEP_DISCRETE_VECTOR); !deps->end (DEP_DISCRETE_VECTOR); idx = deps->next (DEP_DISCRETE_VECTOR)) { derivativeDeps->insert (*idx, DEP_DISCRETE_VECTOR); } _traverseAlgebraics (deps, derivativeIndex, derivativeDeps, states, discretes, variableChange, DEP_ALGEBRAIC_DEF, value); _traverseAlgebraics (deps, derivativeIndex, derivativeDeps, states, discretes, variableChange, DEP_ALGEBRAIC_VECTOR_DEF, value); }