示例#1
0
/* 
 * Implementation of Kronecker product. 
 * Eigen has an implementation of the Kronecker product,
 * but it is very slow due to poor memory reservation.
 * See: https://forum.kde.org/viewtopic.php?f=74&t=106955&p=309990&hilit=kronecker#p309990
 * When Eigen update their implementation, and officially support it, we switch to that.
 */
SparseMatrix myKroneckerProduct(const SparseMatrix &A, const SparseMatrix &B)
{
    SparseMatrix AB(A.rows()*B.rows(), A.cols()*B.cols());

    // Reserve memory for AB

    //AB.reserve(A.nonZeros()*B.nonZeros()); // Does not reserve inner vectors (slow)
    //int innernnz = std::ceil(A.nonZeros()*B.nonZeros()/AB.outerSize());
    //AB.reserve(Eigen::VectorXi::Constant(AB.outerSize(), innernnz)); // Assumes equal distribution of non-zeros (slow)

    // Calculate exact number of non-zeros for each inner vector
    Eigen::VectorXi nnzA = Eigen::VectorXi::Zero(A.outerSize());
    Eigen::VectorXi nnzB = Eigen::VectorXi::Zero(B.outerSize());
    Eigen::VectorXi nnzAB = Eigen::VectorXi::Zero(AB.outerSize());
    //innerNonZeros.setZero();

    for (int jA = 0; jA < A.outerSize(); ++jA)
    {
        int nnz = 0;
        for (SparseMatrix::InnerIterator itA(A,jA); itA; ++itA) nnz++;
        nnzA(jA) = nnz;
    }

    for (int jB = 0; jB < B.outerSize(); ++jB)
    {
        int nnz = 0;
        for (SparseMatrix::InnerIterator itB(B,jB); itB; ++itB) nnz++;
        nnzB(jB) = nnz;
    }

    int innz = 0;
    for (int i = 0; i < nnzA.rows(); ++i)
    {
        for (int j = 0; j < nnzB.rows(); ++j)
        {
            nnzAB(innz) = nnzA(i)*nnzB(j);
            innz++;
        }
    }

    AB.reserve(nnzAB);

    // Non-zero tolerance
    double tolerance = std::numeric_limits<SparseMatrix::Scalar>::epsilon();

    // Compute Kronecker product
    for (int jA = 0; jA < A.outerSize(); ++jA)
    {
        for (SparseMatrix::InnerIterator itA(A,jA); itA; ++itA)
        {
            if (std::abs(itA.value()) > tolerance)
            {
                int jrow = itA.row()*B.rows();
                int jcol = itA.col()*B.cols();

                for (int jB = 0; jB < B.outerSize(); ++jB)
                {
                    for (SparseMatrix::InnerIterator itB(B,jB); itB; ++itB)
                    {
                        if (std::abs(itA.value()*itB.value()) > tolerance)
                        {
                            int row = jrow + itB.row();
                            int col = jcol + itB.col();
                            AB.insert(row,col) = itA.value()*itB.value();
                        }
                    }
                }
            }
        }
    }
    AB.makeCompressed();
    return AB;
}
示例#2
0
/**
 * @brief Parses JSON data and assigns it to the given concert object
 *        Handles all types of data from TMDb (info, releases, trailers, images)
 * @param json JSON data
 * @param concert Concert object
 * @param infos List of infos to load
 */
void TMDbConcerts::parseAndAssignInfos(QString json, Concert *concert, QList<int> infos)
{
    qDebug() << "Entered";
    QScriptValue sc;
    QScriptEngine engine;
    sc = engine.evaluate("(" + QString(json) + ")");

    // Infos
    if (sc.property("imdb_id").isValid() && !sc.property("imdb_id").toString().isEmpty())
        concert->setId(sc.property("imdb_id").toString());
    if (infos.contains(ConcertScraperInfos::Title) && sc.property("title").isValid())
        concert->setName(sc.property("title").toString());
    if (infos.contains(ConcertScraperInfos::Overview) && sc.property("overview").isValid() && !sc.property("overview").isNull())
        concert->setOverview(sc.property("overview").toString());
    if (infos.contains(ConcertScraperInfos::Rating) && sc.property("vote_average").isValid())
        concert->setRating(sc.property("vote_average").toNumber());
    if (infos.contains(ConcertScraperInfos::Tagline) && sc.property("tagline").isValid() && !sc.property("tagline").isNull())
        concert->setTagline(sc.property("tagline").toString());
    if (infos.contains(ConcertScraperInfos::Released) && sc.property("release_date").isValid())
        concert->setReleased(QDate::fromString(sc.property("release_date").toString(), "yyyy-MM-dd"));
    if (infos.contains(ConcertScraperInfos::Runtime) && sc.property("runtime").isValid())
        concert->setRuntime(sc.property("runtime").toInteger());
    if (infos.contains(ConcertScraperInfos::Genres) && sc.property("genres").isArray()) {
        QScriptValueIterator itC(sc.property("genres"));
        while (itC.hasNext()) {
            itC.next();
            QScriptValue vC = itC.value();
            if (vC.property("id").toString().isEmpty())
                continue;
            concert->addGenre(vC.property("name").toString());
        }
    }

    // Trailers
    if (infos.contains(ConcertScraperInfos::Trailer) && sc.property("youtube").isArray()) {
        QScriptValueIterator itC(sc.property("youtube"));
        while (itC.hasNext()) {
            itC.next();
            QScriptValue vC = itC.value();
            if (vC.property("source").toString().isEmpty())
                continue;
            concert->setTrailer(QUrl(Helper::formatTrailerUrl(QString("http://www.youtube.com/watch?v=%1").arg(vC.property("source").toString()))));
            break;
        }
    }

    // Images
    if (infos.contains(ConcertScraperInfos::Backdrop) && sc.property("backdrops").isArray()) {
        QScriptValueIterator itB(sc.property("backdrops"));
        while (itB.hasNext()) {
            itB.next();
            QScriptValue vB = itB.value();
            if (vB.property("file_path").toString().isEmpty())
                continue;
            Poster b;
            b.thumbUrl = m_baseUrl + "w780" + vB.property("file_path").toString();
            b.originalUrl = m_baseUrl + "original" + vB.property("file_path").toString();
            b.originalSize.setWidth(vB.property("width").toString().toInt());
            b.originalSize.setHeight(vB.property("height").toString().toInt());
            concert->addBackdrop(b);
        }
    }

    if (infos.contains(ConcertScraperInfos::Poster) && sc.property("posters").isArray()) {
        QScriptValueIterator itB(sc.property("posters"));
        while (itB.hasNext()) {
            itB.next();
            QScriptValue vB = itB.value();
            if (vB.property("file_path").toString().isEmpty())
                continue;
            Poster b;
            b.thumbUrl = m_baseUrl + "w342" + vB.property("file_path").toString();
            b.originalUrl = m_baseUrl + "original" + vB.property("file_path").toString();
            b.originalSize.setWidth(vB.property("width").toString().toInt());
            b.originalSize.setHeight(vB.property("height").toString().toInt());
            concert->addPoster(b);
        }
    }

    // Releases
    if (infos.contains(ConcertScraperInfos::Certification) && sc.property("countries").isArray()) {
        QString locale;
        QString us;
        QString gb;
        QScriptValueIterator itB(sc.property("countries"));
        while (itB.hasNext()) {
            itB.next();
            QScriptValue vB = itB.value();
            if (vB.property("iso_3166_1").toString() == "US")
                us = vB.property("certification").toString();
            if (vB.property("iso_3166_1").toString() == "GB")
                gb = vB.property("certification").toString();
            if (vB.property("iso_3166_1").toString().toLower() == m_language)
                locale = vB.property("certification").toString();
        }
        if (!locale.isEmpty())
            concert->setCertification(locale);
        else if (!us.isEmpty())
            concert->setCertification(us);
        else if (!gb.isEmpty())
            concert->setCertification(gb);
    }

}