void AbstractUniform::update(Program * program) { assert(program != nullptr); if (!program->isLinked()) { return; } if (!m_cacheDSA) // TODO: move caching to a per context caching { m_cacheDSA = true; m_directStateAccess = hasExtension(GLOW_EXT_direct_state_access); } if (m_directStateAccess) { setValueAt(program, locationFor(program)); } else { program->use(); setValueAt(locationFor(program)); } }
void MrgSorter::merge ( int start, int middle, int end ) { int newCapacity = ( end - start ) + 1; SorterClass<DateType> tmpVector( newCapacity ); int lhIndex = 0; int rhIndex = middle - start + 1; int tmpMid = middle - start; int tmpEnd = end - start; int thisIndex = start; sorterNCopy( tmpVector, *this, start, end ); // Sort elements into result list while( lhIndex <= tmpMid && rhIndex <= tmpEnd ) { if( compareTo( tmpVector[ lhIndex ], tmpVector[ rhIndex ] ) <= 0 ) { setValueAt( thisIndex, tmpVector[ lhIndex ] ); lhIndex++; thisIndex++; } else { setValueAt( thisIndex, tmpVector[ rhIndex ] ); rhIndex++; thisIndex++; } } // Take care of any leftover elements while( lhIndex <= tmpMid ) { setValueAt( thisIndex, tmpVector[ lhIndex ] ); lhIndex++; thisIndex++; } while( rhIndex <= tmpEnd ) { setValueAt( thisIndex, tmpVector[ rhIndex ] ); rhIndex++; thisIndex++; } }
/*! \internal Does one iteration towards a better solution for the problem. See 'solveMaxHelper'. */ bool QSimplex::iterate() { // Find Pivot column int pivotColumn = findPivotColumn(); if (pivotColumn == -1) return false; // Find Pivot row for column int pivotRow = pivotRowForColumn(pivotColumn); if (pivotRow == -1) { qWarning() << "QSimplex: Unbounded problem!"; return false; } // Normalize Pivot Row qreal pivot = valueAt(pivotRow, pivotColumn); if (pivot != 1.0) combineRows(pivotRow, pivotRow, (qreal(1.0) - pivot) / pivot); // Update other rows for (int row=0; row < rows; ++row) { if (row == pivotRow) continue; combineRows(row, pivotRow, -1 * valueAt(row, pivotColumn)); } // Update first column setValueAt(pivotRow, 0, pivotColumn); // dumpMatrix(); // qDebug("------------ end of iteration --------------\n"); return true; }
/**************************************************************************** * Creates a matrix that is the product of the given scalar value and * * the input matrix and returns a pointer to the result matrix. * * Use create(), getValueAt(), and setValueAt() functions to implement * * this function. * * DO NOT modify the input matrix. * ***************************************************************************/ Matrix *scalarMultiply(Matrix *m, int scalar) { Matrix *result = NULL; // TO DO result = create(m->rows, m->columns); for(int row = 0; row < m->rows; row++) { for(int col = 0; col < m->columns; col++) { setValueAt(result,row,col,scalar*getValueAt(m,row,col)); } } return result; }
/**************************************************************************** * Creates the transpose matrix of the input matrix and returns a pointer * * to the result matrix. Use create(), getValueAt(), and setValueAt() * * functions to implement this function. * * DO NOT modify the input matrix. * ***************************************************************************/ Matrix *transpose(Matrix *m) { Matrix *result = NULL; // TO DO result = create(m->columns, m->rows); for(int row = 0; row < m->rows; row++) { for(int col = 0; col < m->columns; col++) { setValueAt(result,col,row,getValueAt(m, row, col)); } } return result; }
/**************************************************************************** * If rows and column of matrix is valid (>0) then read matrix data and * * set the "data" array with these values. Use "setValueAt" function to * * set the values of the matrix. If dimensions are not valid, do nothing. * ***************************************************************************/ void load(Matrix *m) { int value; if (m->rows <= 0 || m->columns <= 0 || m->data == NULL) { return; } for (int i = 1; i <= m->rows; i++) { printf("Enter %d integer values for row %d: ", m->columns, i); for (int j = 1; j <= m->columns; j++) { scanf("%d", &value); setValueAt(m,i-1,j-1,value); } } getchar(); // ignore newline character }
/** * \brief Read XML row element */ bool Column::XmlReadRow(XmlStreamReader * reader) { Q_ASSERT(reader->isStartElement() && reader->name() == "row"); QString str; QXmlStreamAttributes attribs = reader->attributes(); bool ok; int index = reader->readAttributeInt("index", &ok); if(!ok) { reader->raiseError(i18n("invalid or missing row index")); return false; } str = reader->readElementText(); switch(columnMode()) { case AbstractColumn::Numeric: { double value = str.toDouble(&ok); if(!ok) { reader->raiseError(i18n("invalid row value")); return false; } setValueAt(index, value); break; } case AbstractColumn::Text: setTextAt(index, str); break; case AbstractColumn::DateTime: case AbstractColumn::Month: case AbstractColumn::Day: QDateTime date_time = QDateTime::fromString(str,"yyyy-dd-MM hh:mm:ss:zzz"); setDateTimeAt(index, date_time); break; } return true; }
/**************************************************************************** * If the input matrices are compatible, then performs matrix subtraction * * and returns a pointer to the result matrix. * * Use create(), getValueAt(), and setValueAt() functions to implement this * * function. If the input matrices are not compatible, return NULL. * * DO NOT modify the input matrices. * ***************************************************************************/ Matrix *subtract(Matrix *m1, Matrix *m2) { Matrix *result = NULL; // TO DO if(m1->rows == m2->rows && m1->columns == m2->columns) { result = create(m1->rows, m1->columns); for(int row = 0; row < m1->rows; row++) { for(int col = 0; col < m1->columns; col++) { setValueAt(result, row, col, (getValueAt(m1, row,col) - getValueAt(m2,row,col))); } } } return result; }
/**************************************************************************** * If the input matrices are compatible, then multiplies the input matrices * * and returns a pointer to the result matrix. Use create(), getValueAt(), * * and setValueAt() functions to implement this function. * * * * * If the input matrices are not compatible, return NULL. * * DO NOT modify the input matrices. * * ***************************************************************************/ Matrix *multiply(Matrix *m1, Matrix *m2) { Matrix *result = NULL; if(m1->rows == m2->rows && m1->columns == m2->columns) { result = create(m1->rows, m1->columns); for(int row = 0; row < m1->rows; row++) { for(int col = 0; col < m1->columns; col++) { //printf("1. Row: %d Col: %d\n", row, col); int value = (getValueAt(m1, row,col) * getValueAt(m2,row,col)); //printf("2. Row: %d Col: %d\n", row, col); setValueAt(result, row, col, value); } } } return result; }
/*! \internal Both solveMin and solveMax are interfaces to this method. The enum solverFactor admits 2 values: Minimum (-1) and Maximum (+1). This method sets the original objective and runs the second phase Simplex to obtain the optimal solution for the problem. As the internal simplex solver is only able to _maximize_ objectives, we handle the minimization case by inverting the original objective and then maximizing it. */ qreal QSimplex::solver(solverFactor factor) { // Remove old objective clearRow(0); // Set new objective in the first row of the simplex matrix qreal resultOffset = 0; QHash<QSimplexVariable *, qreal>::const_iterator iter; for (iter = objective->variables.constBegin(); iter != objective->variables.constEnd(); ++iter) { // Check if the variable was removed in the simplification process. // If so, we save its offset to the objective function and skip adding // it to the matrix. if (iter.key()->index == -1) { resultOffset += iter.value() * iter.key()->result; continue; } setValueAt(0, iter.key()->index, -1 * factor * iter.value()); } solveMaxHelper(); collectResults(); #ifdef QT_DEBUG for (int i = 0; i < constraints.size(); ++i) { Q_ASSERT(constraints[i]->isSatisfied()); } #endif // Return the value calculated by the simplex plus the value of the // fixed variables. return (factor * valueAt(0, columns - 1)) + resultOffset; }
int main(){ // Ver http://www.webcid.com.br/?pg=calendario&ano=1999 Element * setembro1999 = makeArray(31); Dia diaNormal; diaNormal.feriado = false; diaNormal.lua = 0; for(int i=1; i<=30; i++){ setValueAt(setembro1999, i, diaNormal); } Dia diaDaIndependencia; diaNormal.feriado = true; setValueAt(setembro1999, 7, diaDaIndependencia); Dia diaDeLua; diaDeLua.lua = 3; // 2/7 lua crescente setValueAt(setembro1999, 2, diaDeLua); diaDeLua.lua = 3; // 10/7 lua cheia setValueAt(setembro1999, 10, diaDeLua); diaDeLua.lua = 4; // 17/7 lua minguante setValueAt(setembro1999, 17, diaDeLua); diaDeLua.lua = 1; // 24/7 lua nova setValueAt(setembro1999, 24, diaDeLua); Dia dia = getValueAt(setembro1999, 7); assert(dia.feriado); dia = getValueAt(setembro1999, 10); assert(dia.lua == 3); Dia dia9_9_99 = getValueAt(setembro1999, 9); assert(!dia9_9_99.feriado); }
/*! \internal Sets the new constraints in the simplex solver and returns whether the problem is feasible. This method sets the new constraints, normalizes them, creates the simplex matrix and runs the first simplex phase. */ bool QSimplex::setConstraints(const QList<QSimplexConstraint *> newConstraints) { //////////////////////////// // Reset to initial state // //////////////////////////// clearDataStructures(); if (newConstraints.isEmpty()) return true; // we are ok with no constraints // Make deep copy of constraints. We need this copy because we may change // them in the simplification method. for (int i = 0; i < newConstraints.size(); ++i) { QSimplexConstraint *c = new QSimplexConstraint; c->constant = newConstraints[i]->constant; c->ratio = newConstraints[i]->ratio; c->variables = newConstraints[i]->variables; constraints << c; } // Remove constraints of type Var == K and replace them for their value. if (!simplifyConstraints(&constraints)) { qWarning() << "QSimplex: No feasible solution!"; clearDataStructures(); return false; } /////////////////////////////////////// // Prepare variables and constraints // /////////////////////////////////////// // Set Variables direct mapping. // "variables" is a list that provides a stable, indexed list of all variables // used in this problem. QSet<QSimplexVariable *> variablesSet; for (int i = 0; i < constraints.size(); ++i) variablesSet += \ QSet<QSimplexVariable *>::fromList(constraints[i]->variables.keys()); variables = variablesSet.toList(); // Set Variables reverse mapping // We also need to be able to find the index for a given variable, to do that // we store in each variable its index. for (int i = 0; i < variables.size(); ++i) { // The variable "0" goes at the column "1", etc... variables[i]->index = i + 1; } // Normalize Constraints // In this step, we prepare the constraints in two ways: // Firstly, we modify all constraints of type "LessOrEqual" or "MoreOrEqual" // by the adding slack or surplus variables and making them "Equal" constraints. // Secondly, we need every single constraint to have a direct, easy feasible // solution. Constraints that have slack variables are already easy to solve, // to all the others we add artificial variables. // // At the end we modify the constraints as follows: // - LessOrEqual: SLACK variable is added. // - Equal: ARTIFICIAL variable is added. // - More or Equal: ARTIFICIAL and SURPLUS variables are added. int variableIndex = variables.size(); QList <QSimplexVariable *> artificialList; for (int i = 0; i < constraints.size(); ++i) { QSimplexVariable *slack; QSimplexVariable *surplus; QSimplexVariable *artificial; Q_ASSERT(constraints[i]->helper.first == 0); Q_ASSERT(constraints[i]->artificial == 0); switch(constraints[i]->ratio) { case QSimplexConstraint::LessOrEqual: slack = new QSimplexVariable; slack->index = ++variableIndex; constraints[i]->helper.first = slack; constraints[i]->helper.second = 1.0; break; case QSimplexConstraint::MoreOrEqual: surplus = new QSimplexVariable; surplus->index = ++variableIndex; constraints[i]->helper.first = surplus; constraints[i]->helper.second = -1.0; // fall through case QSimplexConstraint::Equal: artificial = new QSimplexVariable; constraints[i]->artificial = artificial; artificialList += constraints[i]->artificial; break; } } // All original, slack and surplus have already had its index set // at this point. We now set the index of the artificial variables // as to ensure they are at the end of the variable list and therefore // can be easily removed at the end of this method. firstArtificial = variableIndex + 1; for (int i = 0; i < artificialList.size(); ++i) artificialList[i]->index = ++variableIndex; artificialList.clear(); ///////////////////////////// // Fill the Simplex matrix // ///////////////////////////// // One for each variable plus the Basic and BFS columns (first and last) columns = variableIndex + 2; // One for each constraint plus the objective function rows = constraints.size() + 1; matrix = (qreal *)malloc(sizeof(qreal) * columns * rows); if (!matrix) { qWarning() << "QSimplex: Unable to allocate memory!"; return false; } for (int i = columns * rows - 1; i >= 0; --i) matrix[i] = 0.0; // Fill Matrix for (int i = 1; i <= constraints.size(); ++i) { QSimplexConstraint *c = constraints[i - 1]; if (c->artificial) { // Will use artificial basic variable setValueAt(i, 0, c->artificial->index); setValueAt(i, c->artificial->index, 1.0); if (c->helper.second != 0.0) { // Surplus variable setValueAt(i, c->helper.first->index, c->helper.second); } } else { // Slack is used as the basic variable Q_ASSERT(c->helper.second == 1.0); setValueAt(i, 0, c->helper.first->index); setValueAt(i, c->helper.first->index, 1.0); } QHash<QSimplexVariable *, qreal>::const_iterator iter; for (iter = c->variables.constBegin(); iter != c->variables.constEnd(); ++iter) { setValueAt(i, iter.key()->index, iter.value()); } setValueAt(i, columns - 1, c->constant); } // Set objective for the first-phase Simplex. // Z = -1 * sum_of_artificial_vars for (int j = firstArtificial; j < columns - 1; ++j) setValueAt(0, j, 1.0); // Maximize our objective (artificial vars go to zero) solveMaxHelper(); // If there is a solution where the sum of all artificial // variables is zero, then all of them can be removed and yet // we will have a feasible (but not optimal) solution for the // original problem. // Otherwise, we clean up our structures and report there is // no feasible solution. if ((valueAt(0, columns - 1) != 0.0) && (qAbs(valueAt(0, columns - 1)) > 0.00001)) { qWarning() << "QSimplex: No feasible solution!"; clearDataStructures(); return false; } // Remove artificial variables. We already have a feasible // solution for the first problem, thus we don't need them // anymore. clearColumns(firstArtificial, columns - 2); return true; }