<commit_before>//
//  main.cpp
//  greedRelate
//  Greedy approach of keeping samples
//  Created by Shing Wan Choi on 18/08/2016.
//  Copyright © 2016 Shing Wan Choi. All rights reserved.
//

#include "misc.hpp"
#include <algorithm>
#include <cstdlib>
#include <deque>
#include <fstream>
#include <getopt.h>
#include <iostream>
#include <random>
#include <sstream>
#include <stdexcept>
#include <stdlib.h>
#include <string>
#include <unistd.h>
#include <unordered_map>
#include <vector>

class Sample
{
public:
    // First occurance = itself, therefore occurance = 0
    Sample(std::string name, double pheno, double rand)
        : m_name(name), phenotype(pheno), rand_number(rand)
    {
        occur = 0;
    }
    // add a relative to the current sample
    int add(Sample* related)
    {
        // not sure why
        // TODO: See if we can skip the step of pushing nullptr
        relatives.push_back(nullptr);
        relatives.back() = related;
        m_removed = false;
        occur++;
        return occur;
    }
    int remove()
    {
        // we are going to start cleaning up these relatives.
        // good thing is that the size of this vector will small
        // check if any relatives have more than us. If not, then proceed,
        // otherwise, return
        for (auto&& relative : relatives) {
            if (!relative->removed()
                && (relative->occur > occur
                    || (relative->occur == occur
                        && relative->phenotype < phenotype)
                    || (relative->occur == occur
                        && relative->rand_number > rand_number)
                    || (relative->occur == occur
                        && relative->rand_number == rand_number
                        && relative->m_name > m_name)))
            {
                return 0;
            }
        }
        std::cout << m_name << "\t" << occur << std::endl;
        occur = -1;
        m_removed = true;
        for (auto&& relative : relatives) {
            relative->occur--;
            if (relative->occur <= 0) relative->m_removed = true;
        }
        std::sort(relatives.begin(), relatives.end(), Sample::compare_sample);
        for (auto&& relative : relatives) {
            if (!relative->removed() && relative->occur > 0) {
                relative->remove();
            }
        }
        return occur;
    }

    std::string debug() const
    {
        std::string ocur;           // string which will contain the result
        std::ostringstream convert; // stream used for the conversion
        convert << occur; // insert the textual representation of 'Number' in
                          // the characters in the stream
        ocur = convert.str();
        return m_name + " " + ocur;
    }

    static bool compare_sample(Sample const* a, Sample const* b)
    {
        if (a->occur == b->occur) {
            if (a->phenotype == b->phenotype) {
                if (a->rand_number == b->rand_number) {
                    return a->m_name > b->m_name;
                }
                else
                    return a->rand_number > b->rand_number;
            }
            else
                return a->phenotype < b->phenotype;
        }
        else
            return a->occur > b->occur;
    }

    int get_occur() const { return occur; }
    std::string get_name() const { return m_name; }
    bool removed() const
    {
        // add additional condition where the current sample is removed
        if (occur == 0) return true;
        return m_removed;
    }

private:
    std::vector<Sample*> relatives;
    std::string m_name;
    double phenotype;
    double rand_number; // This is a random number to solve the tie
    int occur;
    bool m_removed = true; // so any samples with invalid pairs will be ignoreds
};

void usage()
{
    fprintf(stderr, " GreedyRelate\n");
    fprintf(stderr, " Sam Choi\n");
    fprintf(stderr, " v1.1.2 ( 2018-01-28 )\n");
    fprintf(stderr, " ==============================\n");
    fprintf(stderr, " This programme will try to minize the number of samples "
                    "that need to\n");
    fprintf(stderr, " be removed due to relatedness\n");
    fprintf(stderr,
            " Samples that should be removed are output to the STDOUT\n ");
    fprintf(stderr, " \n");
    fprintf(stderr, " Usage: GreedyRelate [options] -r <relatedness>\n");
    fprintf(stderr, "       -r | --relate      Relationship file (Required)\n");
    fprintf(stderr, "       -p | --pheno       Phenotype file\n");
    fprintf(stderr, "       -t | --threshold   Relatedness Threshold\n");
    fprintf(stderr,
            "       -s | --seed        Seed for the random number generator\n");
    fprintf(stderr,
            "       -h | --help        Display this help message\n\n\n");
    fprintf(stderr, " Details:\n");
    fprintf(stderr,
            "       Relationship file should have the following format:\n");
    fprintf(stderr, "       ID    Pair    Factor\n\n");
    fprintf(stderr, "       We do assume there is a header line\n\n");
    fprintf(stderr,
            "       Phenotype file should have the following format:\n");
    fprintf(stderr, "       ID    Pheno\n\n");
    fprintf(stderr, "       Again, we do assume there is a header line\n");
    fprintf(stderr,
            "       Note: Phenotype information only used to decide which\n");
    fprintf(stderr,
            "             samples to leave behind when there is a tie,\n");
    fprintf(stderr,
            "             where sample with higher phenotype value will be\n");
    fprintf(stderr, "             retained.\n");
    fprintf(stderr,
            "             When no phenotype information is provided, \n");
    fprintf(stderr,
            "             we will randomly select one sample to remove\n");
}

int main(int argc, char* argv[])
{
    if (argc <= 1) {
        usage();
        exit(0);
    }
    static const char* optString = "r:p:t:s:n:h?";
    static const struct option longOpts[] = {
        {"relate", required_argument, nullptr, 'r'},
        {"pheno", required_argument, nullptr, 'p'},
        {"threshold", required_argument, nullptr, 't'},
        {"thread", required_argument, nullptr, 'n'},
        {"seed", required_argument, nullptr, 't'},
        {"help", no_argument, nullptr, 'h'},
        {nullptr, 0, nullptr, 0}};
    std::string relate_name = "";
    std::string pheno_name = "";
    bool provide_seed = false;
    int seed = 0;
    int thread = 1;
    double threshold = 0.0;
    int longIndex = 0;
    int opt = 0;
    opt = getopt_long(argc, argv, optString, longOpts, &longIndex);
    while (opt != -1) {
        switch (opt)
        {
        case 'r': relate_name = optarg; break;
        case 'p': pheno_name = optarg; break;
        case 't':
            threshold = atof(optarg);
            if (threshold <= 0.0)
                fprintf(stderr,
                        "WARNING: Threshold = %f, will not filter samples\n",
                        threshold);
            break;
        case 's':
            try
            {
                int temp = misc::convert<int>(optarg);
                provide_seed = true;
                seed = temp;
            }
            catch (const std::runtime_error&)
            {
                fprintf(stderr, "Cannot parse the seed into number, will not "
                                "use the provided seed\n");
            }
            break;
        case 'n':
            try
            {
                int temp = misc::convert<int>(optarg);
                thread = temp;
            }
            catch (const std::runtime_error&)
            {
                fprintf(stderr, "Cannot parse the thread into number, will "
                                "only use 1 thread\n");
            }
            if (thread <= 0) {
                fprintf(stderr, "Number of thread must be larger than 0. Will "
                                "use only 1 thread\n");
            }
            break;
        case 'h':
        case '?':
            usage();
            return 0;
            break;
        default:
            throw "Undefined operator, please use --help for more "
                  "information!";
        }
        opt = getopt_long(argc, argv, optString, longOpts, &longIndex);
    }

    std::string line;
    std::unordered_map<std::string, double> phenotype;
    if (!pheno_name.empty()) {
        std::ifstream pheno_file;
        pheno_file.open(pheno_name.c_str());
        if (!pheno_file.is_open()) {
            fprintf(stderr, "ERROR: Cannot open phenotype file %s\n",
                    pheno_name.c_str());
            exit(-1);
        }
        // Assumine phenotype has header?
        getline(pheno_file, line);
        while (getline(pheno_file, line)) {
            misc::trim(line);
            if (line.empty()) continue;
            std::vector<std::string> token = misc::split(line);
            if (token.size() < 2) {
                fprintf(stderr, "ERROR: Phenotype file format incorrect! "
                                "Require at least 2 columns\n");
                exit(-1);
            }
            try
            {
                double factor = 0.0;
                if (token[1].compare("NA") == 0 || token[1].compare("na") == 0)
                    factor = -9;
                else
                    factor = misc::convert<double>(token[1]);
                if (phenotype.find(token[0]) != phenotype.end())
                    fprintf(stderr, "WARNING: Duplicated sample id: %s\n",
                            token[0].c_str());
                phenotype[token[0]] = factor;
            }
            catch (const std::runtime_error&)
            {
                fprintf(stderr, "ERROR: Undefined factor number\n");
            }
        }
        pheno_file.close();
    }

    std::random_device::result_type cur_seed = std::random_device()();
    ;
    if (provide_seed)
        cur_seed = static_cast<std::random_device::result_type>(seed);
    fprintf(stderr, "Seed used: %d\n", cur_seed);
    std::mt19937 rand_gen(cur_seed);
    std::uniform_real_distribution<double> distribution(0.0, 1.0);
    // Read relationship file
    std::ifstream relate;
    relate.open(relate_name.c_str());
    if (!relate.is_open()) {
        fprintf(stderr, "ERROR: Cannot open relationship file %s\n",
                relate_name.c_str());
        exit(-1);
    }
    std::vector<Sample*> sample_list;
    std::unordered_map<std::string, size_t> sample_index;
    std::unordered_map<size_t, size_t> direction; // First size_t = pair, second
                                                  // size_t = index of the
                                                  // neighbour

    // Assume there is a header
    // Or we can add in
    fprintf(stderr,
            "Assuming there is a header file for the relatedness file\n");
    getline(relate, line);
    std::vector<std::string> token;
    size_t sample_idx = 0;
    while (getline(relate, line)) {
        misc::trim(line);
        if (line.empty()) continue;
        token = misc::split(line);
        if (token.size() != 3) {
            fprintf(stderr, "ERROR: Relationship file format incorrect! "
                            "Require 3 columns\n");
            exit(-1);
        }
        std::string id = token[0];
        size_t pair = 0;
        double factor = 0.0;
        try
        {
            pair = misc::convert<size_t>(token[1]);
            factor = misc::convert<double>(token[2]);
        }
        catch (const std::runtime_error&)
        {
            fprintf(stderr, "ERROR: Cannot convert some of the information in "
                            "the relationship file\n");
            fprintf(stderr, "Input: %s\n", line.c_str());
            exit(-1);
        }
        // Now we have id pair and factor
        // Ignore any pairs with relatedness less than our threshold
        if (factor <= threshold) continue;
        double pheno = -9;
        if (phenotype.find(id) != phenotype.end()) pheno = phenotype[id];
        if (sample_index.find(id) == sample_index.end()) {
            // this is a new sample
            sample_list.push_back(
                new Sample(id, pheno, distribution(rand_gen)));
            sample_index[id] = sample_idx;
            ++sample_idx;
        }
        // worst case scenario in UKBB -> 109 relatives
        // still better than resorting the whole vector
        if (direction.find(pair) != direction.end()) {
            // this is not a new pair
            size_t dir_id = direction[pair];
            size_t sam_id = sample_index[id];
            sample_list[dir_id]->add(sample_list[sam_id]);
            sample_list[sam_id]->add(sample_list[dir_id]);
        }
        else
        {
            // a new pair is located
            direction[pair] = sample_index[id];
        }
    }
    // Update phenotype informations
    sample_index.clear();
    std::sort(sample_list.begin(), sample_list.end(), Sample::compare_sample);
    for (auto&& sample : sample_list) {
        if (sample->removed()) continue;
        sample->remove();
    }
    return 0;
}
<commit_msg>Fix edge cases and add --out parameter<commit_after>//
//  main.cpp
//  greedRelate
//  Greedy approach of keeping samples
//  Created by Shing Wan Choi on 18/08/2016.
//  Copyright © 2016 Shing Wan Choi. All rights reserved.
//

#include "misc.hpp"
#include <algorithm>
#include <cstdlib>
#include <deque>
#include <fstream>
#include <getopt.h>
#include <iostream>
#include <random>
#include <sstream>
#include <stdexcept>
#include <stdlib.h>
#include <string>
#include <unistd.h>
#include <unordered_map>
#include <vector>

// Useful for debugging
bool is_problem(const std::string& input)
{
    std::vector<std::string> prob = {};
    for (auto&& p : prob)
    {
        if (input == p) return true;
    }
    return false;
}

class Sample
{
public:
    // First occurance = itself, therefore occurance = 0
    Sample(std::string name, double pheno, double rand)
        : m_name(name), m_phenotype(pheno), m_rand_number(rand)
    {
        m_occur = 0;
    }
    // add a relative to the current sample
    int add(Sample* related)
    {
        // not sure why
        // TODO: See if we can skip the step of pushing nullptr
        // m_relatives.push_back(nullptr);
        // m_relatives.back() = related;
        m_relatives.emplace_back(related);
        m_removed = false;
        m_occur++;
        return m_occur;
    }
    int remove(std::ostream& os)
    {
        // First, check if we should remove any relatives before ourselves
        // If there are any to be removed, remove them first.Then
        // check if we still need to remove ourselves
        // If we no longer need to remove ourselves, immediately stop
        // transversing the relative vector

        // Do sorting first to ensure we remove the most related pair first
        std::sort(m_relatives.begin(), m_relatives.end(),
                  Sample::compare_sample);
        for (auto&& relative : m_relatives)
        {
            if (!relative->removed()
                && (relative->m_occur > m_occur
                    || (relative->m_occur == m_occur
                        && relative->m_phenotype < m_phenotype)
                    || (relative->m_occur == m_occur
                        && relative->m_rand_number > m_rand_number)
                    || (relative->m_occur == m_occur
                        && misc::logically_equal(relative->m_rand_number,
                                                 m_rand_number)
                        && relative->m_name > m_name)))
            {
                // try to remove the relative now
                relative->remove(os);
                // If we have nothing left, end.
                // If we can still remove, then continue on
                if (m_occur <= 0 || m_removed) return 0;
            }
        }
        // if we reach here, it means this sample still need to be removed.
        os << m_name << "\t" << m_occur << std::endl;
        m_occur = -1;
        m_removed = true;
        // Update our relatives to inform them we are dead
        for (auto&& relative : m_relatives)
        {
            relative->m_occur--;
            if (relative->m_occur <= 0) relative->m_removed = true;
        }
        // Now update our relative's ordering before removal. Most likely
        // not required. But should be safer this way as the relative vector
        // should be tiny (< 100 ) anyway.
        std::sort(m_relatives.begin(), m_relatives.end(),
                  Sample::compare_sample);
        for (auto&& relative : m_relatives)
        {
            if (!relative->removed() && relative->m_occur > 0)
            { relative->remove(os); } }
        return m_occur;
    }

    std::string debug() const
    {
        std::string occur;          // string which will contain the result
        std::ostringstream convert; // stream used for the conversion
        convert << m_occur; // insert the textual representation of 'Number' in
                            // the characters in the stream
        occur = convert.str();
        return m_name + " " + occur;
    }

    static bool compare_sample(Sample const* a, Sample const* b)
    {
        // Ordering is based on
        // 1. Who has more related pair? More is first
        // 2. Who has a larger phenotype? Higher come later (reserve cases)
        // 3. Who has a higher random number? Higher come first
        // 4. Who has a larger ID? Do string comparison, larger come first
        if (a->m_occur == b->m_occur)
        {
            if (misc::logically_equal(a->m_phenotype, b->m_phenotype))
            {
                if (misc::logically_equal(a->m_rand_number, b->m_rand_number))
                { return a->m_name > b->m_name; } else
                    return a->m_rand_number > b->m_rand_number;
            }
            else
                return a->m_phenotype < b->m_phenotype;
        }
        else
            return a->m_occur > b->m_occur;
    }

    int get_occur() const { return m_occur; }
    std::string get_name() const { return m_name; }
    bool removed() const
    {
        // add additional condition where the current sample is removed
        return (m_occur == 0 || m_removed);
    }

private:
    std::vector<Sample*> m_relatives;
    std::string m_name;
    double m_phenotype;
    double m_rand_number; // This is a random number to solve the tie
    int m_occur;
    bool m_removed = true; // so any samples with invalid pairs will be ignoreds
};

void usage()
{
    fprintf(stderr, " GreedyRelate\n");
    fprintf(stderr, " Sam Choi\n");
    fprintf(stderr, " v1.1.3 ( 2018-02-04 )\n");
    fprintf(stderr, " ==============================\n");
    fprintf(stderr, " This programme will try to minize the number of samples "
                    "that need to\n");
    fprintf(stderr, " be removed due to relatedness\n");
    fprintf(stderr,
            " Samples that should be removed are output to the STDOUT\n ");
    fprintf(stderr, " \n");
    fprintf(stderr, " Usage: GreedyRelate [options] -r <relatedness>\n");
    fprintf(stderr, "       -r | --relate      Relationship file (Required)\n");
    fprintf(stderr, "       -p | --pheno       Phenotype file\n");
    fprintf(stderr, "       -t | --threshold   Relatedness Threshold\n");
    fprintf(stderr,
            "       -o | --out         Output name. Stdout if not provided\n");
    fprintf(stderr,
            "       -s | --seed        Seed for the random number generator\n");
    fprintf(stderr,
            "       -h | --help        Display this help message\n\n\n");
    fprintf(stderr, " Details:\n");
    fprintf(stderr,
            "       Relationship file should have the following format:\n");
    fprintf(stderr, "       ID    Pair    Factor\n\n");
    fprintf(stderr, "       We do assume there is a header line\n\n");
    fprintf(stderr,
            "       Phenotype file should have the following format:\n");
    fprintf(stderr, "       ID    Pheno\n\n");
    fprintf(stderr, "       Again, we do assume there is a header line\n");
    fprintf(stderr,
            "       Note: Phenotype information only used to decide which\n");
    fprintf(stderr,
            "             samples to leave behind when there is a tie,\n");
    fprintf(stderr,
            "             where sample with higher phenotype value will be\n");
    fprintf(stderr, "             retained.\n");
    fprintf(stderr,
            "             When no phenotype information is provided, \n");
    fprintf(stderr,
            "             we will randomly select one sample to remove\n");
}

int main(int argc, char* argv[])
{
    if (argc <= 1)
    {
        usage();
        exit(0);
    }
    static const char* optString = "r:p:t:s:n:o:h?";
    static const struct option longOpts[] = {
        {"relate", required_argument, nullptr, 'r'},
        {"pheno", required_argument, nullptr, 'p'},
        {"threshold", required_argument, nullptr, 't'},
        {"thread", required_argument, nullptr, 'n'},
        {"seed", required_argument, nullptr, 't'},
        {"out", required_argument, nullptr, 'o'},
        {"help", no_argument, nullptr, 'h'},
        {nullptr, 0, nullptr, 0}};
    std::string relate_name = "";
    std::string pheno_name = "";
    std::string out_name = "";

    bool provide_seed = false;
    int seed = 0;
    int thread = 1;
    double threshold = 0.0;
    int longIndex = 0;
    int opt = 0;
    opt = getopt_long(argc, argv, optString, longOpts, &longIndex);
    while (opt != -1)
    {
        switch (opt)
        {
        case 'r': relate_name = optarg; break;
        case 'p': pheno_name = optarg; break;
        case 't':
            threshold = atof(optarg);
            if (threshold <= 0.0)
                fprintf(stderr,
                        "WARNING: Threshold = %f, will not filter samples\n",
                        threshold);
            break;
        case 's':
            try
            {
                int temp = misc::convert<int>(optarg);
                provide_seed = true;
                seed = temp;
            }
            catch (const std::runtime_error&)
            {
                fprintf(stderr, "Cannot parse the seed into number, will not "
                                "use the provided seed\n");
            }
            break;
        case 'o': out_name = optarg; break;
        case 'n':
            try
            {
                int temp = misc::convert<int>(optarg);
                thread = temp;
            }
            catch (const std::runtime_error&)
            {
                fprintf(stderr, "Cannot parse the thread into number, will "
                                "only use 1 thread\n");
            }
            if (thread <= 0)
            {
                fprintf(stderr, "Number of thread must be larger than 0. Will "
                                "use only 1 thread\n");
            }
            break;
        case 'h':
        case '?':
            usage();
            return 0;
            break;
        default:
            throw "Undefined operator, please use --help for more "
                  "information!";
        }
        opt = getopt_long(argc, argv, optString, longOpts, &longIndex);
    }
    std::ostream* fp = &std::cout;
    std::ofstream fout;
    if (!out_name.empty())
    {
        fout.open(out_name.c_str());
        if (!fout.is_open()){
            fprintf(stderr, "ERROR: Cannot open output file to write: %s\n", out_name.c_str());
            exit(-1);
        }
            fp = &fout;
    }
    std::string line;
    std::unordered_map<std::string, double> phenotype;
    if (!pheno_name.empty())
    {
        std::ifstream pheno_file;
        pheno_file.open(pheno_name.c_str());
        if (!pheno_file.is_open())
        {
            fprintf(stderr, "ERROR: Cannot open phenotype file %s\n",
                    pheno_name.c_str());
            exit(-1);
        }
        // Assumine phenotype has header?
        getline(pheno_file, line);
        while (getline(pheno_file, line))
        {
            misc::trim(line);
            if (line.empty()) continue;
            std::vector<std::string> token = misc::split(line);
            if (token.size() < 2)
            {
                fprintf(stderr, "ERROR: Phenotype file format incorrect! "
                                "Require at least 2 columns\n");
                exit(-1);
            }
            try
            {
                double factor = 0.0;
                if (token[1].compare("NA") == 0 || token[1].compare("na") == 0)
                    factor = -9;
                else
                    factor = misc::convert<double>(token[1]);
                if (phenotype.find(token[0]) != phenotype.end())
                    fprintf(stderr, "WARNING: Duplicated sample id: %s\n",
                            token[0].c_str());
                phenotype[token[0]] = factor;
            }
            catch (const std::runtime_error&)
            {
                fprintf(stderr, "ERROR: Undefined factor number\n");
            }
        }
        pheno_file.close();
    }

    std::random_device::result_type cur_seed = std::random_device()();
    ;
    if (provide_seed)
        cur_seed = static_cast<std::random_device::result_type>(seed);
    fprintf(stderr, "Seed used: %d\n", cur_seed);
    std::mt19937 rand_gen(cur_seed);
    std::uniform_real_distribution<double> distribution(0.0, 1.0);
    // Read relationship file
    std::ifstream relate;
    relate.open(relate_name.c_str());
    if (!relate.is_open())
    {
        fprintf(stderr, "ERROR: Cannot open relationship file %s\n",
                relate_name.c_str());
        exit(-1);
    }
    std::vector<Sample*> sample_list;
    std::unordered_map<std::string, size_t> sample_index;
    std::unordered_map<size_t, size_t> direction; // First size_t = pair, second
                                                  // size_t = index of the
                                                  // neighbour

    // Assume there is a header
    // Or we can add in
    fprintf(stderr,
            "Assuming there is a header file for the relatedness file\n");
    getline(relate, line);
    std::vector<std::string> token;
    size_t sample_idx = 0;
    while (getline(relate, line))
    {
        misc::trim(line);
        if (line.empty()) continue;
        token = misc::split(line);
        if (token.size() != 3)
        {
            fprintf(stderr, "ERROR: Relationship file format incorrect! "
                            "Require 3 columns\n");
            exit(-1);
        }
        std::string id = token[0];
        size_t pair = 0;
        double factor = 0.0;
        try
        {
            pair = misc::convert<size_t>(token[1]);
            factor = misc::convert<double>(token[2]);
        }
        catch (const std::runtime_error&)
        {
            fprintf(stderr, "ERROR: Cannot convert some of the information in "
                            "the relationship file\n");
            fprintf(stderr, "Input: %s\n", line.c_str());
            exit(-1);
        }
        // Now we have id pair and factor
        // Ignore any pairs with relatedness less than our threshold
        if (factor <= threshold) continue;
        double pheno = -9;
        if (phenotype.find(id) != phenotype.end()) pheno = phenotype[id];
        if (sample_index.find(id) == sample_index.end())
        {
            // this is a new sample
            sample_list.push_back(
                new Sample(id, pheno, distribution(rand_gen)));
            sample_index[id] = sample_idx;
            ++sample_idx;
        }
        // worst case scenario in UKBB -> 109 relatives
        // still better than resorting the whole vector
        if (direction.find(pair) != direction.end())
        {
            // this is not a new pair
            size_t dir_id = direction[pair];
            size_t sam_id = sample_index[id];
            sample_list[dir_id]->add(sample_list[sam_id]);
            sample_list[sam_id]->add(sample_list[dir_id]);
        }
        else
        {
            // a new pair is located
            direction[pair] = sample_index[id];
        }
    }
    // Update phenotype informations
    sample_index.clear();
    std::sort(sample_list.begin(), sample_list.end(), Sample::compare_sample);
    for (auto&& sample : sample_list)
    {
        if (sample->removed()) continue;
        sample->remove(*fp);
    }
    return 0;
}
<|endoftext|>


<commit_before>#include "dcmtk/config/osconfig.h"   // make sure OS specific configuration is included first

// UIDs
#include "QIICRUIDs.h"

// versioning
#include "dcmqiVersionConfigure.h"

#include "dcmtk/ofstd/ofstream.h"
#include "dcmtk/ofstd/oftest.h"
#include "dcmtk/ofstd/ofstd.h"

#include "dcmtk/dcmsr/dsrdoc.h"
#include "dcmtk/dcmdata/dcfilefo.h"
#include "dcmtk/dcmiod/modhelp.h"

#include "dcmtk/dcmsr/codes/dcm.h"
#include "dcmtk/dcmsr/codes/srt.h"
#include "dcmtk/dcmsr/cmr/tid1500.h"

#include "dcmtk/dcmdata/dcdeftag.h"

#include <iostream>
#include <exception>

#include <json/json.h>

#include "Exceptions.h"

using namespace std;

// not used yet
static OFLogger dcemfinfLogger = OFLog::getLogger("qiicr.apps");

#include "tid1500readerCLP.h"

#define CHECK_BOOL(condition) \
  do { \
    if (!condition) { \
      std::cerr << "Expected True in " __FILE__ << ":" << __LINE__ << " " << std::cout; \
      throw -1; \
    } \
  } while (0);

#define STATIC_ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))

DSRCodedEntryValue json2cev(Json::Value& j){
  return DSRCodedEntryValue(j["codeValue"].asCString(),
    j["codingSchemeDesignator"].asCString(),
    j["codeMeaning"].asCString());
}

void addFileToEvidence(DSRDocument &doc, string dirStr, string fileStr){
  DcmFileFormat ff;
  OFString fullPath;
  CHECK_COND(ff.loadFile(OFStandard::combineDirAndFilename(fullPath,dirStr.c_str(),fileStr.c_str())));
  CHECK_COND(doc.getCurrentRequestedProcedureEvidence().addItem(*ff.getDataset()));
}

bool isCompositeEvidence(OFString& sopClassUID) {
  const char* compositeContextSOPClasses[] = {UID_SegmentationStorage, UID_RealWorldValueMappingStorage};
  int length = sizeof(compositeContextSOPClasses)/sizeof(*compositeContextSOPClasses);
  for( unsigned int i=0; i<length; i++)
  {
    cout << "compare " + sopClassUID + " with " + compositeContextSOPClasses[i] << endl;
    if (sopClassUID == compositeContextSOPClasses[i])
      return true;
  }
  return false;
}

int main(int argc, char** argv){
  PARSE_ARGS;

  Json::Value metaRoot;

  DcmFileFormat sliceFF;
  CHECK_COND(sliceFF.loadFile(inputSRFileName.c_str()));
  DcmDataset* dataset = sliceFF.getDataset();

  DSRDocument doc;

  CHECK_COND(doc.read(*dataset));

  OFString temp;
  doc.getSeriesDescription(temp);
  metaRoot["SeriesDescription"] = temp.c_str();
  doc.getSeriesNumber(temp);
  metaRoot["SeriesNumber"] = temp.c_str();
  doc.getInstanceNumber(temp);
  metaRoot["InstanceNumber"] = temp.c_str();

  Json::Value compositeContextUIDs(Json::arrayValue);
  Json::Value imageLibraryUIDs(Json::arrayValue);

  DSRSOPInstanceReferenceList &evidenceList = doc.getCurrentRequestedProcedureEvidence();
  OFCondition cond = evidenceList.gotoFirstItem();
  OFString sopInstanceUID;
  OFString sopClassUID;
  while(cond.good()) {
    evidenceList.getSOPClassUID(sopClassUID);
    evidenceList.getSOPInstanceUID(sopInstanceUID).c_str();
    if (isCompositeEvidence(sopClassUID)) {
      cout << "add composite" << endl;
      compositeContextUIDs.append(sopInstanceUID.c_str());
    }else {
      cout << "add image library" << endl;
      imageLibraryUIDs.append(sopInstanceUID.c_str());
    }
    cond = evidenceList.gotoNextItem();
  }
  if (!imageLibraryUIDs.empty())
    metaRoot["imageLibrary"] = imageLibraryUIDs;
  if (!compositeContextUIDs.empty())
    metaRoot["compositeContext"] = compositeContextUIDs;

  ofstream outputFile;

  outputFile.open(metaDataFileName.c_str());

  outputFile << metaRoot;
  outputFile.close();

  return 0;
}<commit_msg>ENH: Only measurementItems missing and then it should read the complete SR into JSON (issue #88)<commit_after>#include "dcmtk/config/osconfig.h"   // make sure OS specific configuration is included first

// UIDs
#include "QIICRUIDs.h"

// versioning
#include "dcmqiVersionConfigure.h"

#include "dcmtk/ofstd/ofstream.h"
#include "dcmtk/ofstd/oftest.h"
#include "dcmtk/ofstd/ofstd.h"

#include "dcmtk/dcmsr/dsrdoc.h"
#include "dcmtk/dcmdata/dcfilefo.h"
#include "dcmtk/dcmiod/modhelp.h"

#include "dcmtk/dcmsr/codes/dcm.h"
#include "dcmtk/dcmsr/codes/srt.h"
#include "dcmtk/dcmsr/cmr/tid1500.h"

#include "dcmtk/dcmdata/dcdeftag.h"

#include <iostream>
#include <exception>

#include <json/json.h>

#include "Exceptions.h"

#include "Helper.h"

using namespace std;

// not used yet
static OFLogger dcemfinfLogger = OFLog::getLogger("qiicr.apps");

#include "tid1500readerCLP.h"

#define CHECK_BOOL(condition) \
  do { \
    if (!condition) { \
      std::cerr << "Expected True in " __FILE__ << ":" << __LINE__ << " " << std::cout; \
      throw -1; \
    } \
  } while (0);

#define STATIC_ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))

DSRCodedEntryValue json2cev(Json::Value& j){
  return DSRCodedEntryValue(j["codeValue"].asCString(),
                            j["codingSchemeDesignator"].asCString(),
                            j["codeMeaning"].asCString());
}

void addFileToEvidence(DSRDocument &doc, string dirStr, string fileStr){
  DcmFileFormat ff;
  OFString fullPath;
  CHECK_COND(ff.loadFile(OFStandard::combineDirAndFilename(fullPath,dirStr.c_str(),fileStr.c_str())));
  CHECK_COND(doc.getCurrentRequestedProcedureEvidence().addItem(*ff.getDataset()));
}

bool isCompositeEvidence(OFString& sopClassUID) {
  const char* compositeContextSOPClasses[] = {UID_SegmentationStorage, UID_RealWorldValueMappingStorage};
  int length = sizeof(compositeContextSOPClasses)/sizeof(*compositeContextSOPClasses);
  for( unsigned int i=0; i<length; i++)
    if (sopClassUID == compositeContextSOPClasses[i])
      return true;
  return false;
}

Json::Value getMeasurements(DSRDocument &doc) {
  Json::Value measurements(Json::arrayValue);
  DSRDocumentTree &st = doc.getTree();

  DSRDocumentTreeNodeCursor cursor;
  st.getCursorToRootNode(cursor);
  if(st.gotoNamedChildNode(CODE_DCM_ImagingMeasurements)) {
    // can have 1-n MeasurementGroups
    do {
      if (st.gotoNamedChildNode(CODE_DCM_MeasurementGroup)) {
        Json::Value measurement;
        if (st.gotoNamedChildNode(DSRCodedEntryValue("C67447", "NCIt", "Activity Session"))) {
          // TODO: think about it
          cout << "Activity Session: " << st.getCurrentContentItem().getStringValue().c_str() << endl;
          measurement["ActivitySession"] = st.getCurrentContentItem().getStringValue().c_str();
          st.gotoParent();
        }
        if (st.gotoNamedChildNode(CODE_DCM_ReferencedSegment, OFFalse)) {
          DSRImageReferenceValue bla;
          cout << "segmentationSOPInstanceUID: " << st.getCurrentContentItem().getImageReference().getSOPInstanceUID() << endl;
          OFVector<Uint16> items;
          st.getCurrentContentItem().getImageReference().getSegmentList().getItems(items);
          cout << "Reference Segment: " << items[0]  << endl;
          measurement["ReferencedSegment"] = dcmqi::Helper::toString(items[0]);
          measurement["segmentationSOPInstanceUID"] = st.getCurrentContentItem().getImageReference().getSOPInstanceUID().c_str();
          st.gotoParent();
        }
        if (st.gotoNamedChildNode(CODE_DCM_TrackingIdentifier, OFFalse)) {
          cout << "TrackingIdentifier: " << st.getCurrentContentItem().getStringValue().c_str() << endl;
          measurement["TrackingIdentifier"] = st.getCurrentContentItem().getStringValue().c_str();
          st.gotoParent();
        }
        if (st.gotoNamedChildNode(CODE_DCM_Finding)) {
          measurement["Finding"]["CodeMeaning"] = st.getCurrentContentItem().getCodeValue().getCodeMeaning().c_str();
          measurement["Finding"]["CodeSchemeDesignator"] = st.getCurrentContentItem().getCodeValue().getCodingSchemeDesignator().c_str();
          measurement["Finding"]["CodeValue"] = st.getCurrentContentItem().getCodeValue().getCodeValue().c_str();
          st.gotoParent();
        }
        if (st.gotoNamedChildNode(DSRCodedEntryValue("G-C0E3", "SRT", "Finding Site"))) {
          measurement["FindingSite"]["CodeMeaning"] = st.getCurrentContentItem().getCodeValue().getCodeMeaning().c_str();
          measurement["FindingSite"]["CodeSchemeDesignator"] = st.getCurrentContentItem().getCodeValue().getCodingSchemeDesignator().c_str();
          measurement["FindingSite"]["CodeValue"] = st.getCurrentContentItem().getCodeValue().getCodeValue().c_str();
          st.gotoParent();
        }
        measurements.append(measurement);
      }
    } while (st.gotoNextNamedNode(CODE_DCM_MeasurementGroup));
  }
  return measurements;
}

int main(int argc, char** argv){
  PARSE_ARGS;

  Json::Value metaRoot;

  DcmFileFormat sliceFF;
  CHECK_COND(sliceFF.loadFile(inputSRFileName.c_str()));
  DcmDataset* dataset = sliceFF.getDataset();

  TID1500_MeasurementReport report(CMR_CID7021::ImagingMeasurementReport);
  DSRDocument doc;

  CHECK_COND(doc.read(*dataset));

  OFString temp;
  doc.getSeriesDescription(temp);
  metaRoot["SeriesDescription"] = temp.c_str();
  doc.getSeriesNumber(temp);
  metaRoot["SeriesNumber"] = temp.c_str();
  doc.getInstanceNumber(temp);
  metaRoot["InstanceNumber"] = temp.c_str();

  cout << "Number of verifying observers: " << doc.getNumberOfVerifyingObservers() << endl;

  OFString observerName, observingDateTime, organizationName;
  if (doc.getNumberOfVerifyingObservers() != 0) {
    doc.getVerifyingObserver(1, observingDateTime, observerName, organizationName);
    metaRoot["observerContext"]["ObserverType"] = "PERSON";
    metaRoot["observerContext"]["PersonObserverName"] = observerName.c_str();
  }

  metaRoot["VerificationFlag"] = DSRTypes::verificationFlagToEnumeratedValue(doc.getVerificationFlag());
  metaRoot["CompletionFlag"] = DSRTypes::completionFlagToEnumeratedValue(doc.getCompletionFlag());

  Json::Value compositeContextUIDs(Json::arrayValue);
  Json::Value imageLibraryUIDs(Json::arrayValue);

  // TODO: We need to think about that, because actually the file names are stored in the json and not the UIDs
  DSRSOPInstanceReferenceList &evidenceList = doc.getCurrentRequestedProcedureEvidence();
  OFCondition cond = evidenceList.gotoFirstItem();
  OFString sopInstanceUID;
  OFString sopClassUID;
  while(cond.good()) {
    evidenceList.getSOPClassUID(sopClassUID);
    evidenceList.getSOPInstanceUID(sopInstanceUID).c_str();
    if (isCompositeEvidence(sopClassUID)) {
//      cout << "add composite" << endl;
      compositeContextUIDs.append(sopInstanceUID.c_str());
    }else {
//      cout << "add image library" << endl;
      imageLibraryUIDs.append(sopInstanceUID.c_str());
    }
    cond = evidenceList.gotoNextItem();
  }
  if (!imageLibraryUIDs.empty())
    metaRoot["imageLibrary"] = imageLibraryUIDs;
  if (!compositeContextUIDs.empty())
    metaRoot["compositeContext"] = compositeContextUIDs;

  metaRoot["Measurements"] = getMeasurements(doc);

  ofstream outputFile;

  outputFile.open(metaDataFileName.c_str());

  outputFile << metaRoot;
  outputFile.close();

//  std::filebuf fb;
//  fb.open (metaDataFileName.c_str(),std::ios::out);
//
//  ostream out(&fb);
//  DSRDocumentTree &st = doc.getTree();
//  st.print(out);
//  fb.close();

  return 0;
}<|endoftext|>


<commit_before>8d3f40fa-4b02-11e5-811f-28cfe9171a43<commit_msg>OKAY this time it should work<commit_after>8d4e8614-4b02-11e5-86f6-28cfe9171a43<|endoftext|>


<commit_before>#include <iostream>

//Thomas' Prototypes

//Hannah's Prototypes

//Kate's Prototypes

int (main)
{
using nedit file...
create new input "hannah's test changes"
}

<commit_msg>Kate's Updated Prototype<commit_after>#include <iostream>

//Thomas' Prototypes

//Hannah's Prototypes

int atomic_distance (int distance); //Kate's Prototype: defines atomic distance as integer

int (main)
{
using nedit file...
create new input "hannah's test changes"
}

<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>
#include "image.h"
#include "utils.h"

//TODO:: Attempt to compensate for font width vs height
//TODO:: Add a preserve aspect ratio

//Scaling and transform variables
float fontHeight = 1.0;
float fontWidth = 0.6;
float zoom_ratio = 1.0;
int panX = 0;
int panY = 0;
int imgHeight = 100;
int imgWidth = 100;
int frame = 0;

using namespace ::cv;
using namespace ::std;

//Example for passing in a function that can use different strings in the picture
string charAtPos(int i, int j) {
    if (i < 5 && j < 5) {
        return "t";
    }
    return "";
}

//TODO:: Get data on render time
int main(int argc, char *argv[]) {

    if (argc < 2) {
        cout << "This program requires a image, video, document or textfile as an argument" << endl;
        return 1;
    }

    //Setup Screen
    int termWidth, termHeight;
    getTerminalSize(termWidth, termHeight);
    //    system("setterm -cursor off");
    //    system ("/bin/stty cooked");
    //    system("export PS1=\"\"");

    //setup vars
    Mat img;
    Mat dst;
    VideoCapture capture;

    //Default Settings
    FileType ft = NONE;
    bool preserveAspectRatio = false;
    bool interactive = false;
    bool writeToFile = false;
    vector<string> allArgs(argv, argv + argc);

    String filename = setOptions(allArgs, &preserveAspectRatio, &interactive, &writeToFile, &ft);

    if (ft == VID) {
        capture.open(filename);
    }

    do {
        //TODO:: Is performance improved if the whole video is loaded into a buffer?
        if (ft == VID) {
            bool success = capture.read(img);
            if (!success) {
                return 0;
            }
            capture >> img;
            frame++;
        }
        //This will convert doc files to tmp-0.png tmp-1.png etc.
        else if (ft == DOC) {
            string cmd = "convert " + filename + " tmp.png";
            system(cmd.c_str());
            char buffer[10];
            snprintf(buffer, 10, "%d", frame);
            img = imread("tmp-" + (string) buffer + ".png", CV_LOAD_IMAGE_COLOR);
        } else if (ft == IMG) {
            img = imread(filename, CV_LOAD_IMAGE_COLOR);
        } else if (ft == TXT) {
            printFile(filename, frame * termHeight, (frame + 1) * termHeight);
        } else {
            cout << "That's not a valid file!" << endl;
            return 1;
        }
        //TODO:: Make the zoomin go straight in to center
        if (ft != TXT) {
            int rw = img.size().width * zoom_ratio;
            int rh = img.size().height* zoom_ratio;
            panX = bound(0,panX, img.size().width-rw);
            panY = bound(0,panY, img.size().height-rh);
            Mat roi = img(Rect(panX, panY, rw, rh));
            resize(roi, dst, Size(termWidth, termHeight));
            cout << matToPixels(dst, charAtPos);
            if (writeToFile) {
                char buffer[10];
                snprintf(buffer, 10, "%d", frame);
                string outFileName = filename + "-textart" + buffer;
                ofstream outFile;
                outFile.open(outFileName.c_str());
                outFile << matToPixels(dst);
            }
        }

        if (interactive) {
            userInput(&frame, &panX, &panY, &zoom_ratio, imgWidth, imgHeight);
        }

    } while (ft == VID || interactive);

    return 0;
}

<commit_msg>Implemented preserve aspect ratio flag<commit_after>#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>
#include "image.h"
#include "utils.h"

//TODO:: Attempt to compensate for font width vs height
//TODO:: Add a preserve aspect ratio

//Scaling and transform variables
float fontHeight = 1.0;
float fontWidth = 0.6;
float zoom_ratio = 1.0;
int panX = 0;
int panY = 0;
int imgHeight = 100;
int imgWidth = 100;
int frame = 0;

using namespace ::cv;
using namespace ::std;

//Example for passing in a function that can use different strings in the picture
string charAtPos(int i, int j) {
    if (i < 5 && j < 5) {
        return "";
    }
    return "";
}

//TODO:: Get data on render time
int main(int argc, char *argv[]) {

    if (argc < 2) {
        cout << "This program requires a image, video, document or textfile as an argument" << endl;
        return 1;
    }

    //Setup Screen
    int termWidth, termHeight;
    getTerminalSize(termWidth, termHeight);
    //    system("setterm -cursor off");
    //    system ("/bin/stty cooked");
    //    system("export PS1=\"\"");

    //setup vars
    Mat img;
    Mat dst;
    VideoCapture capture;

    //Default Settings
    FileType ft = NONE;
    bool preserveAspectRatio = false;
    bool interactive = false;
    bool writeToFile = false;
    vector<string> allArgs(argv, argv + argc);

    String filename = setOptions(allArgs, &preserveAspectRatio, &interactive, &writeToFile, &ft);

    if (ft == VID) {
        capture.open(filename);
    }

    do {
        //TODO:: Is performance improved if the whole video is loaded into a buffer?
        if (ft == VID) {
            bool success = capture.read(img);
            if (!success) {
                return 0;
            }
            capture >> img;
            frame++;
        }
        //This will convert doc files to tmp-0.png tmp-1.png etc.
        else if (ft == DOC) {
            string cmd = "convert " + filename + " tmp.png";
            system(cmd.c_str());
            char buffer[10];
            snprintf(buffer, 10, "%d", frame);
            img = imread("tmp-" + (string) buffer + ".png", CV_LOAD_IMAGE_COLOR);
        } else if (ft == IMG) {
            img = imread(filename, CV_LOAD_IMAGE_COLOR);
        } else if (ft == TXT) {
            printFile(filename, frame * termHeight, (frame + 1) * termHeight);
        } else {
            cout << "That's not a valid file!" << endl;
            return 1;
        }
        //TODO:: Make the zoomin go straight in to center
        if (ft != TXT) {
            int rw = img.size().width * zoom_ratio;
            int rh = img.size().height* zoom_ratio;
            panX = bound(0,panX, img.size().width-rw);
            panY = bound(0,panY, img.size().height-rh);
            Mat roi = img(Rect(panX, panY, rw, rh));
            float par = 1.0;
            if(preserveAspectRatio){
                par = 0.6;
            }
            resize(roi, dst, Size(termWidth*par, termHeight));
            cout << matToPixels(dst, charAtPos);
            if (writeToFile) {
                char buffer[10];
                snprintf(buffer, 10, "%d", frame);
                string outFileName = filename + "-textart" + buffer;
                ofstream outFile;
                outFile.open(outFileName.c_str());
                outFile << matToPixels(dst);
            }
        }

        if (interactive) {
            userInput(&frame, &panX, &panY, &zoom_ratio, imgWidth, imgHeight);
            cout <<"\033c";
        }

    } while (ft == VID || interactive);

    return 0;
}

<|endoftext|>


<commit_before>272af89e-ad5d-11e7-a599-ac87a332f658<commit_msg>Fixed that one bug<commit_after>27e06773-ad5d-11e7-b564-ac87a332f658<|endoftext|>


<commit_before>f7828175-2747-11e6-a861-e0f84713e7b8<commit_msg>Adding stuff<commit_after>f78ec380-2747-11e6-bb7c-e0f84713e7b8<|endoftext|>


<commit_before>d9363078-2747-11e6-b33c-e0f84713e7b8<commit_msg>Fixed that one bug<commit_after>d944bc6b-2747-11e6-be41-e0f84713e7b8<|endoftext|>


<commit_before>7fa8964a-2749-11e6-9a5b-e0f84713e7b8<commit_msg>No longer crashes if X<commit_after>7fb9df85-2749-11e6-9c8f-e0f84713e7b8<|endoftext|>


<commit_before>7a49f1f5-2749-11e6-a97f-e0f84713e7b8<commit_msg>almost working<commit_after>7a5a3c63-2749-11e6-ab5f-e0f84713e7b8<|endoftext|>


<commit_before>// Xerus - A General Purpose Tensor Library
// Copyright (C) 2014-2015 Benjamin Huber and Sebastian Wolf.
//
// Xerus is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// Xerus is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with Xerus. If not, see <http://www.gnu.org/licenses/>.
//
// For further information on Xerus visit https://libXerus.org
// or contact us at contact@libXerus.org.

#include "include/xerus.h"
#include <stdio.h>
#include <fstream>

void storeVeloData(xerus::FullTensor &_v, std::string _fname) {
	std::vector<size_t> oldDim = _v.dimensions;
	_v.reinterpret_dimensions(std::vector<size_t>({25,27,25,3}));
	std::ofstream outX(_fname+"_vx.dat");
	std::ofstream outY(_fname+"_vy.dat");
	std::ofstream outZ(_fname+"_vz.dat");
	for (size_t x=0; x<25; x+=1) {
		for (size_t y=0; y<27; y+=1) {
			outX << _v[{x,y,10,0}] << " ";
			outY << _v[{x,y,10,1}] << " ";
			outZ << _v[{x,y,10,2}] << " ";
		}
		outX << std::endl;
		outY << std::endl;
		outZ << std::endl;
	}
	outX.close();
	outY.close();
	outZ.close();
	_v.reinterpret_dimensions(oldDim);
}

void swap_endianness(size_t *n) {
	size_t res=0;
	while (*n != 0) {
		res <<= 8;
		res += (*n) | 0xFF;
		*n >>= 8;
	}
	*n = res;
}

int main() {
	std::ifstream in("cgv_013.bin", std::ios::binary);
	xerus::FullTensor velocity({25,27,25,3});
	velocity.factor = 1.0;
// 	for(size_t i = 0; i < 25*27*25*3; ++i) {
// 		in.read(reinterpret_cast<char*>(velocity.data.get()+i), sizeof(double));
// 		REQUIRE(!in.fail(), "");
// 	}
	in.read(reinterpret_cast<char*>(velocity.data.get()), 25*27*25*3*sizeof(double));
	in.close();
	std::cout << velocity[0] << ' ' << velocity[1] << std::endl;
	velocity.reinterpret_dimensions(std::vector<size_t>({5,5,3,9,5,5,3}));

	storeVeloData(velocity, "channel_full");

	xerus::TTTensor ttv(velocity);
	xerus::TTOperator I(xerus::TTOperator::construct_identity({5,5,3,9,5,5,3,  5,5,3,9,5,5,3}));
	size_t r = xerus::misc::max(ttv.ranks())-1;
	xerus::value_t velo_norm = xerus::frob_norm(velocity);
	std::ofstream out("channel_ttapprox.dat");
	xerus::TTTensor ttvOpt(ttv);
	for (r=20; r>0; --r) {
		std::cout << r << '\r' << std::flush;
		ttv.round(r);
		std::cout << r << " als" << '\r' << std::flush;
// 		std::vector<double> perf;
// 		xerus::ALS(I, ttv, ttvOpt, 1e-4, &perf);
		xerus::FullTensor approx(ttv);
		out << r << " "
		    << xerus::frob_norm(approx-velocity)/velo_norm << " "
 			<< ttv.datasize() << std::endl;
		storeVeloData(approx, "channel_r"+std::to_string(r));
	}
	out.close();

    return 0;
}
<commit_msg>corrected read-in of the turbulence data<commit_after>// Xerus - A General Purpose Tensor Library
// Copyright (C) 2014-2015 Benjamin Huber and Sebastian Wolf.
//
// Xerus is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// Xerus is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with Xerus. If not, see <http://www.gnu.org/licenses/>.
//
// For further information on Xerus visit https://libXerus.org
// or contact us at contact@libXerus.org.

#include "include/xerus.h"
#include <stdio.h>
#include <fstream>

void storeVeloData(xerus::FullTensor &_v, std::string _fname) {
	std::vector<size_t> oldDim = _v.dimensions;
	_v.reinterpret_dimensions(std::vector<size_t>({25,27,25,3}));
	std::ofstream outX(_fname+"_vx.dat");
	std::ofstream outY(_fname+"_vy.dat");
	std::ofstream outZ(_fname+"_vz.dat");
	for (size_t x=0; x<25; x+=1) {
		for (size_t y=0; y<27; y+=1) {
			outX << _v[{x,y,10,0}] << " ";
			outY << _v[{x,y,10,1}] << " ";
			outZ << _v[{x,y,10,2}] << " ";
		}
		outX << std::endl;
		outY << std::endl;
		outZ << std::endl;
	}
	outX.close();
	outY.close();
	outZ.close();
	_v.reinterpret_dimensions(oldDim);
}

void swap_endianness(size_t *n) {
	size_t res=0;
	while (*n != 0) {
		res <<= 8;
		res += (*n) | 0xFF;
		*n >>= 8;
	}
	*n = res;
}

int main() {
	std::ifstream in("cgv_013.bin", std::ios::binary);
	xerus::FullTensor velocity({3,25,27,25});
	velocity.factor = 1.0;
	xerus::Index i1,i2,i3,i4;
// 	for(size_t i = 0; i < 25*27*25*3; ++i) {
// 		in.read(reinterpret_cast<char*>(velocity.data.get()+i), sizeof(double));
// 		REQUIRE(!in.fail(), "");
// 	}
	in.read(reinterpret_cast<char*>(velocity.data.get()), 25*27*25*3*sizeof(double));
	in.close();
	velocity(i1,i2,i3,i4) = velocity(i4,i3,i2,i1);
	velocity.reinterpret_dimensions(std::vector<size_t>({5,5,3,9,5,5,3}));

	storeVeloData(velocity, "channel_full");

	xerus::TTTensor ttv(velocity);
	xerus::TTOperator I(xerus::TTOperator::construct_identity({5,5,3,9,5,5,3,  5,5,3,9,5,5,3}));
	size_t r = xerus::misc::max(ttv.ranks())-1;
	xerus::value_t velo_norm = xerus::frob_norm(velocity);
	std::ofstream out("channel_ttapprox.dat");
	xerus::TTTensor ttvOpt(ttv);
	for (; r>0; --r) {
		std::cout << r << '\r' << std::flush;
		ttv.round(r);
		std::cout << r << " als" << '\r' << std::flush;
		std::vector<double> perf;
		xerus::ALSVariant alsb(xerus::ALS);
		alsb.printProgress = true;
		alsb(I, ttv, ttvOpt, 1e-4, &perf);
		xerus::FullTensor approx(ttv);
		out << r << " "
		    << xerus::frob_norm(approx-velocity)/velo_norm << " "
 			<< ttv.datasize() << std::endl;
		storeVeloData(approx, "channel_r"+std::to_string(r));
	}
	out.close();

    return 0;
}
<|endoftext|>


<commit_before>#ifndef GNR_MANY_HPP
# define GNR_MANY_HPP
# pragma once

#include <cstddef>

#include <tuple>

#include <type_traits>

#include <utility>

namespace gnr
{

namespace detail
{

namespace many
{

enum TupleValue { Scalar, Reference, Class };

template <std::size_t I,
  class T,
  TupleValue = std::is_class<T>{} ?
    TupleValue::Class :
    std::is_reference<T>{} ?
      TupleValue::Reference :
      TupleValue::Scalar
>
struct tuple_base
{
  T value;

  tuple_base() = default;

  template <typename A>
  constexpr tuple_base(A&& value) : value{std::forward<A>(value)}
  {
  }

  tuple_base(tuple_base const&) = default;
  tuple_base(tuple_base&&) = default;
  tuple_base& operator=(tuple_base const&) = default;
  tuple_base& operator=(tuple_base&&) = default;
};

template <std::size_t I, class T>
struct tuple_base<I, T, TupleValue::Reference>
{
  T value;

  tuple_base() = delete;

  template <typename A>
  constexpr tuple_base(A&& value) : value{std::forward<A>(value)}
  {
  }

  tuple_base(tuple_base const&) = default;
  tuple_base(tuple_base&&) = default;
  tuple_base& operator=(tuple_base const&) = default;
  tuple_base& operator=(tuple_base&&) = default;
};

template <std::size_t I, class T>
struct tuple_base<I, T, TupleValue::Class> : T
{
  tuple_base() = default;

  template <typename A>
  constexpr tuple_base(A&& value) : T{std::forward<A>(value)}
  {
  }

  tuple_base(tuple_base const&) = default;
  tuple_base(tuple_base&&) = default;
  tuple_base& operator=(tuple_base const&) = default;
  tuple_base& operator=(tuple_base&&) = default;
};

template <std::size_t I, class T, enum detail::many::TupleValue E>
auto& get(tuple_base<I, T, E> const& obj) noexcept
{
  return obj.value;
}

template <std::size_t I, class T>
auto get(tuple_base<I, T, TupleValue::Class>& obj) noexcept -> T&
{
  return obj;
}

template <std::size_t I, class T>
auto get(tuple_base<I, T, TupleValue::Class> const& obj) noexcept -> T const&
{
  return obj;
}

template <typename ...>
struct many_impl;

template <std::size_t... Is, typename ...Types>
struct many_impl<std::index_sequence<Is...>, Types...> :
  tuple_base<Is, Types>...
{
  many_impl() = default;

  ~many_impl() = default;
  many_impl(many_impl const&) = default;
  many_impl(many_impl&&) = default;
  many_impl& operator=(many_impl const&) = default;
  many_impl& operator=(many_impl&&) = default;

#if !__cpp_aggregate_bases
  template<typename ...U>
  constexpr many_impl(U&& ...u) :
    tuple_base<Is, Types>{std::forward<U>(u)}...
  {
  }
#endif
};

}

}

template <typename ...Types>
struct many : detail::many::many_impl<
  std::make_index_sequence<sizeof...(Types)>,
  Types...
>
{
  many() = default;

  ~many() = default;
  many(many&&) = default;
  many(many const&) = default;
  many& operator=(many&&) = default;
  many& operator=(many const&) = default;

#if !__cpp_aggregate_bases
  template <class... U>
  constexpr many(U&& ...u) : many::many_impl{std::forward<U>(u)...}
  {
  }
#endif
};

}

namespace std
{

template <typename ...Types>
class tuple_size<gnr::many<Types...>> :
  public std::integral_constant<size_t, sizeof...(Types)>
{
};

template <size_t I, class ...Types>
class tuple_element<I, gnr::many<Types...>>
{
public:
  using type = tuple_element_t<I, tuple<Types...>>;
};

template <size_t I, typename ...Types>
auto& get(gnr::many<Types...>& m) noexcept
{
  return gnr::detail::many::get<I>(m);
}

template <size_t I, typename ...Types>
auto& get(gnr::many<Types...> const& m) noexcept
{
  return gnr::detail::many::get<I>(m);
}

template<size_t I, typename ...Types>
auto& get(gnr::many<Types...>&& m) noexcept
{
  // m is now a lvalue
  return gnr::detail::many::get<I>(m);
}

template<size_t I, typename ...Types>
auto& get(gnr::many<Types...> const&& m) noexcept
{
  // m is now a lvalue
  return gnr::detail::many::get<I>(m);
}

}

#endif // GNR_MANY_HPP
<commit_msg>some fixes<commit_after>#ifndef GNR_MANY_HPP
# define GNR_MANY_HPP
# pragma once

#include <cstddef>

#include <type_traits>

#include <utility>

namespace gnr
{

namespace detail
{

namespace many
{

enum TupleValue { Scalar, Reference, Class };

template <std::size_t I,
  class T,
  TupleValue = std::is_class<T>{} ?
    TupleValue::Class :
    std::is_reference<T>{} ?
      TupleValue::Reference :
      TupleValue::Scalar
>
struct tuple_base
{
  T value;

  tuple_base() = default;

  template <typename A>
  constexpr tuple_base(A&& value) : value{std::forward<A>(value)}
  {
  }

  tuple_base(tuple_base const&) = default;
  tuple_base(tuple_base&&) = default;
  tuple_base& operator=(tuple_base const&) = default;
  tuple_base& operator=(tuple_base&&) = default;
};

template <std::size_t I, class T>
struct tuple_base<I, T, TupleValue::Reference>
{
  T value;

  tuple_base() = delete;

  template <typename A>
  constexpr tuple_base(A&& value) : value{std::forward<A>(value)}
  {
  }

  tuple_base(tuple_base const&) = default;
  tuple_base(tuple_base&&) = default;
  tuple_base& operator=(tuple_base const&) = default;
  tuple_base& operator=(tuple_base&&) = default;
};

template <std::size_t I, class T>
struct tuple_base<I, T, TupleValue::Class> : T
{
  tuple_base() = default;

  template <typename A>
  constexpr tuple_base(A&& value) : T{std::forward<A>(value)}
  {
  }

  tuple_base(tuple_base const&) = default;
  tuple_base(tuple_base&&) = default;
  tuple_base& operator=(tuple_base const&) = default;
  tuple_base& operator=(tuple_base&&) = default;
};

template <std::size_t I, class T, enum detail::many::TupleValue E>
auto& get(tuple_base<I, T, E> const& obj) noexcept
{
  return obj.value;
}

template <std::size_t I, class T>
auto get(tuple_base<I, T, TupleValue::Class>& obj) noexcept -> T&
{
  return obj;
}

template <std::size_t I, class T>
auto get(tuple_base<I, T, TupleValue::Class> const& obj) noexcept -> T const&
{
  return obj;
}

template <typename ...>
struct many_impl;

template <std::size_t... Is, typename ...Types>
struct many_impl<std::index_sequence<Is...>, Types...> :
  tuple_base<Is, Types>...
{
  many_impl() = default;

  ~many_impl() = default;
  many_impl(many_impl const&) = default;
  many_impl(many_impl&&) = default;
  many_impl& operator=(many_impl const&) = default;
  many_impl& operator=(many_impl&&) = default;

#if !__cpp_aggregate_bases
  template<typename ...U>
  constexpr many_impl(U&& ...u) :
    tuple_base<Is, Types>{std::forward<U>(u)}...
  {
  }
#endif
};

}

}

template <typename ...Types>
struct many : detail::many::many_impl<
  std::make_index_sequence<sizeof...(Types)>,
  Types...
>
{
  many() = default;

  ~many() = default;
  many(many&&) = default;
  many(many const&) = default;
  many& operator=(many&&) = default;
  many& operator=(many const&) = default;

#if !__cpp_aggregate_bases
  template <class... U>
  constexpr many(U&& ...u) : many::many_impl{std::forward<U>(u)...}
  {
  }
#endif
};

}

namespace std
{

template <typename ...Types>
class tuple_size<gnr::many<Types...>> :
  public std::integral_constant<size_t, sizeof...(Types)>
{
};

template <size_t I, class ...Types>
class tuple_element<I, gnr::many<Types...>>
{
public:
  using type = tuple_element_t<I, tuple<Types...>>;
};

template <size_t I, typename ...Types>
auto& get(gnr::many<Types...>& m) noexcept
{
  return gnr::detail::many::get<I>(m);
}

template <size_t I, typename ...Types>
auto& get(gnr::many<Types...> const& m) noexcept
{
  return gnr::detail::many::get<I>(m);
}

template<size_t I, typename ...Types>
auto& get(gnr::many<Types...>&& m) noexcept
{
  // m is now a lvalue
  return gnr::detail::many::get<I>(m);
}

template<size_t I, typename ...Types>
auto& get(gnr::many<Types...> const&& m) noexcept
{
  // m is now a lvalue
  return gnr::detail::many::get<I>(m);
}

}

#endif // GNR_MANY_HPP
<|endoftext|>


<commit_before>#include <QtCore/QFile>
#include <QtCore/QStringList>
#include <QtCore/QTextStream>
#include <QtGui/QVector2D>
#include "math.hpp"

qreal Polynom::operator()(qreal x, qreal y) const {
	qreal result = 0;
	for (ConstIterator i = begin(); i != end(); ++i) {
		result += qPow(x, i->xPow) * qPow(y, i->yPow) * i->c;
	}
	return result;
}

qreal Polynom::operator()(QPointF point) const {
	return operator()(point.x(), point.y());
}

Polynom Polynom::differentiateX() const {
	Polynom result;
	Monom m;
	for (ConstIterator i = begin(); i != end(); ++i) {
		if (i->xPow) {
			m.xPow = i->xPow - 1;
			m.yPow = i->yPow;
			m.c = i->c * i->xPow;
			result.push_back(m);
		}
	}
	return result;
}

Polynom Polynom::differentiateY() const {
	Polynom result;
	Monom m;
	for (ConstIterator i = begin(); i != end(); ++i) {
		if (i->yPow) {
			m.xPow = i->xPow;
			m.yPow = i->yPow - 1;
			m.c = i->c * i->yPow;
			result.push_back(m);
		}
	}
	return result;
}

QPointF PolynomSystem::getNextValue(QPointF point, qreal eps, bool useRungeKutta) const {
	QVector2D diff(first(point), second(point));
	if (useRungeKutta) {
		qreal x = point.x(), y = point.y();
		qreal first25  = first (x + eps * first(point) / 2, y + eps * second(point) / 2);
		qreal second25 = second(x + eps * first(point) / 2, y + eps * second(point) / 2);
		qreal first50  = first (x + eps * first25 / 2, y + eps * second25 / 2);
		qreal second50 = second(x + eps * first25 / 2, y + eps * second25 / 2);
		qreal first75  = first (x + eps * first50, y + eps * second50);
		qreal second75 = second(x + eps * first50, y + eps * second50);
		diff.setX((first (point) + 2 * first25  + 2 * first50  + first75 ) / 6);
		diff.setY((second(point) + 2 * second25 + 2 * second50 + second75) / 6);
	}
	if (diff.length() > 1) {
		diff /= diff.length();
	}
	diff *= eps;
	return point + diff.toPointF();
}

qreal PolynomSystem::poincareFunction(qreal p, qreal eps) const {
	QPointF point(p, 0);
	quint32 step = 0;
	while (step < 20 || point.x() < 0 || qAbs(point.y()) > eps) {
		point = getNextValue(point, eps);
		if (step > 50. / eps) {
			return 0;
		}
		++step;
	}
	return point.x();
}

qreal PolynomSystem::findPoincareStaticPoint(qreal a, qreal b, qreal eps) const {
	qreal pdiffa = poincareFunction(a, eps) - a;
	qreal pdiffb = poincareFunction(b, eps) - b;
	if (pdiffa * pdiffb > 0) {
		return 0;
	}
	while (qAbs(b - a) > eps) {
		pdiffa = poincareFunction(a, eps) - a;
		pdiffb = poincareFunction(b, eps) - b;
		a = b - (b - a) * pdiffb / (pdiffb - pdiffa);
		pdiffa = poincareFunction(a, eps) - a;
		b = a - (a - b) * pdiffa / (pdiffa - pdiffb);
	}
	return b;
}

qreal PolynomSystem::getPeriod(qreal staticPoint, qreal eps) const {
	QPointF point(staticPoint, 0);
	quint32 step = 0;
	qreal diff = 0;
	while (step < 5 || qAbs(diff) > eps / 2) {
		point = getNextValue(point, eps, true);
		diff = qPow(point.x() - staticPoint, 2) + qPow(point.y(), 2);
		++step;
	}
	return step * eps;
}

void fillPolynom(QString line, Polynom &polynom, qreal param) {
	QStringList parts = line.split("  ");
	QStringList subParts;
	Monom m;
	polynom.clear();
	for (int i = 0; i < parts.size(); ++i) {
		subParts = parts.at(i).split(' ');
		m.xPow = subParts.at(1).toInt();
		m.yPow = subParts.at(2).toInt();
		m.c = subParts.at(0) == "c" ? param : subParts.at(0).toDouble();
		polynom.append(m);
	}
}

ComplexPair PolynomSystem::getEigenValues(QPointF point) const {
	ComplexPair result;
	qreal a = first.differentiateX()(point),
	      b = first.differentiateY()(point),
	      c = second.differentiateX()(point),
	      d = second.differentiateY()(point);
	qreal determinant = (a - d) * (a - d) + 4 * b * c;
	Complex detSqrt = std::sqrt(Complex(determinant, 0));
	result.first  = (Complex(a + d, 0) + detSqrt) * Complex(.5, 0);
	result.second = (Complex(a + d, 0) - detSqrt) * Complex(.5, 0);
	return result;
}

PointType PolynomSystem::getPointType(QPointF point) const {
	ComplexPair eigenValues = getEigenValues(point);
	Complex v1 = eigenValues.first, v2 = eigenValues.second;
	if (qFuzzyIsNull(v1.real()) && qFuzzyIsNull(v2.real())) {
		return PointCenter;
	} else if (qFuzzyIsNull(v1.imag()) && qFuzzyIsNull(v2.imag())) {
		if (qFuzzyCompare(v1.real(), v2.real())) {
			if (v1.real() > 0) {
				return PointKnotSingularUnstable;
			} else {
				return PointKnotSingularStable;
			}
		} else if (v1.real() > 0 && v2.real() > 0) {
			return PointKnotUnstable;
		} else if (v1.real() < 0 && v2.real() < 0) {
			return PointKnotStable;
		} else {
			return PointSaddle;
		}
	} else if (v1.real() > 0) {
		return PointFocusUnstable;
	} else {
		return PointFocusStable;
	}
}

void fillSystem(QString fileName, PolynomSystem &system, qreal param) {
	QFile inputFile(fileName);
	inputFile.open(QFile::ReadOnly);
	QTextStream input(&inputFile);
	fillPolynom(input.readLine(), system.first, param);
	fillPolynom(input.readLine(), system.second, param);
	inputFile.close();
}
<commit_msg>Fix division by zero in findPoincareStaticPoint<commit_after>#include <QtCore/QFile>
#include <QtCore/QStringList>
#include <QtCore/QTextStream>
#include <QtGui/QVector2D>
#include "math.hpp"

qreal Polynom::operator()(qreal x, qreal y) const {
	qreal result = 0;
	for (ConstIterator i = begin(); i != end(); ++i) {
		result += qPow(x, i->xPow) * qPow(y, i->yPow) * i->c;
	}
	return result;
}

qreal Polynom::operator()(QPointF point) const {
	return operator()(point.x(), point.y());
}

Polynom Polynom::differentiateX() const {
	Polynom result;
	Monom m;
	for (ConstIterator i = begin(); i != end(); ++i) {
		if (i->xPow) {
			m.xPow = i->xPow - 1;
			m.yPow = i->yPow;
			m.c = i->c * i->xPow;
			result.push_back(m);
		}
	}
	return result;
}

Polynom Polynom::differentiateY() const {
	Polynom result;
	Monom m;
	for (ConstIterator i = begin(); i != end(); ++i) {
		if (i->yPow) {
			m.xPow = i->xPow;
			m.yPow = i->yPow - 1;
			m.c = i->c * i->yPow;
			result.push_back(m);
		}
	}
	return result;
}

QPointF PolynomSystem::getNextValue(QPointF point, qreal eps, bool useRungeKutta) const {
	QVector2D diff(first(point), second(point));
	if (useRungeKutta) {
		qreal x = point.x(), y = point.y();
		qreal first25  = first (x + eps * first(point) / 2, y + eps * second(point) / 2);
		qreal second25 = second(x + eps * first(point) / 2, y + eps * second(point) / 2);
		qreal first50  = first (x + eps * first25 / 2, y + eps * second25 / 2);
		qreal second50 = second(x + eps * first25 / 2, y + eps * second25 / 2);
		qreal first75  = first (x + eps * first50, y + eps * second50);
		qreal second75 = second(x + eps * first50, y + eps * second50);
		diff.setX((first (point) + 2 * first25  + 2 * first50  + first75 ) / 6);
		diff.setY((second(point) + 2 * second25 + 2 * second50 + second75) / 6);
	}
	if (diff.length() > 1) {
		diff /= diff.length();
	}
	diff *= eps;
	return point + diff.toPointF();
}

qreal PolynomSystem::poincareFunction(qreal p, qreal eps) const {
	QPointF point(p, 0);
	quint32 step = 0;
	while (step < 20 || point.x() < 0 || qAbs(point.y()) > eps) {
		point = getNextValue(point, eps);
		if (step > 50. / eps) {
			return 0;
		}
		++step;
	}
	return point.x();
}

qreal PolynomSystem::findPoincareStaticPoint(qreal a, qreal b, qreal eps) const {
	qreal pdiffa = poincareFunction(a, eps) - a;
	qreal pdiffb = poincareFunction(b, eps) - b;
	if (pdiffa * pdiffb > 0) {
		return 0;
	}
	while (qAbs(b - a) > eps) {
		pdiffa = poincareFunction(a, eps) - a;
		pdiffb = poincareFunction(b, eps) - b;
		if (qFuzzyCompare(pdiffa, pdiffb)) {
			break;
		}
		a = b - (b - a) * pdiffb / (pdiffb - pdiffa);
		pdiffa = poincareFunction(a, eps) - a;
		if (qFuzzyCompare(pdiffa, pdiffb)) {
			break;
		}
		b = a - (a - b) * pdiffa / (pdiffa - pdiffb);
	}
	return b;
}

qreal PolynomSystem::getPeriod(qreal staticPoint, qreal eps) const {
	QPointF point(staticPoint, 0);
	quint32 step = 0;
	qreal diff = 0;
	while (step < 5 || qAbs(diff) > eps / 2) {
		point = getNextValue(point, eps, true);
		diff = qPow(point.x() - staticPoint, 2) + qPow(point.y(), 2);
		++step;
	}
	return step * eps;
}

void fillPolynom(QString line, Polynom &polynom, qreal param) {
	QStringList parts = line.split("  ");
	QStringList subParts;
	Monom m;
	polynom.clear();
	for (int i = 0; i < parts.size(); ++i) {
		subParts = parts.at(i).split(' ');
		m.xPow = subParts.at(1).toInt();
		m.yPow = subParts.at(2).toInt();
		m.c = subParts.at(0) == "c" ? param : subParts.at(0).toDouble();
		polynom.append(m);
	}
}

ComplexPair PolynomSystem::getEigenValues(QPointF point) const {
	ComplexPair result;
	qreal a = first.differentiateX()(point),
	      b = first.differentiateY()(point),
	      c = second.differentiateX()(point),
	      d = second.differentiateY()(point);
	qreal determinant = (a - d) * (a - d) + 4 * b * c;
	Complex detSqrt = std::sqrt(Complex(determinant, 0));
	result.first  = (Complex(a + d, 0) + detSqrt) * Complex(.5, 0);
	result.second = (Complex(a + d, 0) - detSqrt) * Complex(.5, 0);
	return result;
}

PointType PolynomSystem::getPointType(QPointF point) const {
	ComplexPair eigenValues = getEigenValues(point);
	Complex v1 = eigenValues.first, v2 = eigenValues.second;
	if (qFuzzyIsNull(v1.real()) && qFuzzyIsNull(v2.real())) {
		return PointCenter;
	} else if (qFuzzyIsNull(v1.imag()) && qFuzzyIsNull(v2.imag())) {
		if (qFuzzyCompare(v1.real(), v2.real())) {
			if (v1.real() > 0) {
				return PointKnotSingularUnstable;
			} else {
				return PointKnotSingularStable;
			}
		} else if (v1.real() > 0 && v2.real() > 0) {
			return PointKnotUnstable;
		} else if (v1.real() < 0 && v2.real() < 0) {
			return PointKnotStable;
		} else {
			return PointSaddle;
		}
	} else if (v1.real() > 0) {
		return PointFocusUnstable;
	} else {
		return PointFocusStable;
	}
}

void fillSystem(QString fileName, PolynomSystem &system, qreal param) {
	QFile inputFile(fileName);
	inputFile.open(QFile::ReadOnly);
	QTextStream input(&inputFile);
	fillPolynom(input.readLine(), system.first, param);
	fillPolynom(input.readLine(), system.second, param);
	inputFile.close();
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: frqitem.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-04-11 19:19:23 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _FRQITEM_HXX
#define _FRQITEM_HXX

#ifndef _RTTI_HXX
#include <tools/rtti.hxx>
#endif

#ifndef _TOOLS_TIME_HXX //autogen
#include <tools/time.hxx>
#endif

#ifndef _DATETIME_HXX //autogen
#include <tools/datetime.hxx>
#endif

#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif

#include <svtools/poolitem.hxx>

class SvStream;

DBG_NAMEEX(SfxFrequencyItem)

// class SfxFrequencyItem -------------------------------------------------

///////////////////////////////////////////////////////////////////////////////
/*
FRQ_DAILY
    * jeden X'ten Tag
    nInterval1 = 1 .. 999

    * jeden Wochentag
    nInterval1 = USHRT_MAX

FRQ_WEEKLY
    + wiederhole jede X'te Woche
    nInterval1 = 1 .. 99

    + an SU, MO, TU, WE, TH, FR, SA
    nInterval2 = WD_SUNDAY | WD_MONDAY | WD_TUESDAY | WD_WEDNESDAY |
                 WD_THURSDAY | WD_FRIDAY | WD_SATURDAY

FRQ_MONTHLY_DAILY
    * jeden X'ten Tag von jedem X'ten Monat
    nInterval1 = 1 .. 31
    nInterval2 = 1 .. 6

FRQ_MONTHLY_LOGIC
    * jeden ersten, zweiten, dritten, vierten oder letzten Wochentag jeden X'ten Monats
    nInterval1 = 0 .. 4
    nInterval2 = WD_SUNDAY | WD_MONDAY | WD_TUESDAY | WD_WEDNESDAY |
                 WD_THURSDAY | WD_FRIDAY | WD_SATURDAY
    nInterval3 = 1 .. 6

===============================================================================

FRQ_TIME_AT
    * Update um Uhrzeit
    nTime1 = 00:00:00 - 24:00:00

FRQ_TIME_REPEAT
    * Wiederhole alle X Stunden
    nTInterval1 = 1 .. 8
        + zwischen Uhrzeit 1 und 2
        nTime1 = 00:00:00 - 24:00:00
        nTime2 = 00:00:00 - 24:00:00

*/
///////////////////////////////////////////////////////////////////////////////

enum FrequencyMode
{
    FRQ_DAILY               = 1,
    FRQ_WEEKLY              = 2,
    FRQ_MONTHLY_DAILY       = 3,
    FRQ_MONTHLY_LOGIC       = 4
};

enum FrequencyTimeMode
{
    FRQ_TIME_AT             = 1,
    FRQ_TIME_REPEAT         = 2,
    FRQ_TIME_REPEAT_RANGE   = 3
};

#define WD_SUNDAY       0x0001
#define WD_MONDAY       0x0002
#define WD_TUESDAY      0x0004
#define WD_WEDNESDAY    0x0008
#define WD_THURSDAY     0x0010
#define WD_FRIDAY       0x0020
#define WD_SATURDAY     0x0040

class SfxFrequencyItem : public SfxPoolItem
{
private:
            FrequencyMode       eFrqMode;
            FrequencyTimeMode   eFrqTimeMode;

            USHORT              nDInterval1;
            USHORT              nDInterval2;
            USHORT              nDInterval3;

            USHORT              nTInterval1;
            Time                aTime1;
            Time                aTime2;

            BOOL                bMissingDate;
            DateTime            aMissingDate;

            Time                _CalcTime( BOOL bForToday ) const;
public:
            TYPEINFO();

            SfxFrequencyItem( const SfxFrequencyItem& rCpy );
            SfxFrequencyItem( USHORT nWhich );
            SfxFrequencyItem( USHORT nWhich, FrequencyMode eMode, FrequencyTimeMode eTMode,
                              USHORT nDI1, USHORT nDI2, USHORT nDI3, USHORT nTI1,
                              const Time& rT1, const Time& rT2 );
            ~SfxFrequencyItem() { DBG_DTOR(SfxFrequencyItem, 0); }

    virtual int             operator==( const SfxPoolItem& )            const;
    using SfxPoolItem::Compare;
    virtual int             Compare( const SfxPoolItem &rWith )         const;
    virtual SfxPoolItem*    Create( SvStream&, USHORT nItemVersion )    const;
    virtual SvStream&       Store( SvStream&, USHORT nItemVersion )     const;
    virtual SfxPoolItem*    Clone( SfxItemPool* pPool = 0 )             const;
    virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres,
                                SfxMapUnit eCoreMetric, SfxMapUnit ePresMetric, XubString &rText,
                                const IntlWrapper * = 0 ) const;

    DateTime                CalcNextTick( const DateTime& rNow, BOOL bFirst = FALSE );

    BOOL                    HasMissingDate() const              { return bMissingDate; }
    DateTime                GetMissingDate() const              { return aMissingDate; }

    FrequencyMode           GetFrequencyMode() const            { return eFrqMode; }
    FrequencyTimeMode       GetFrequencyTimeMode() const        { return eFrqTimeMode; }
    USHORT                  GetDInterval_1() const              { return nDInterval1; }
    USHORT                  GetDInterval_2() const              { return nDInterval2; }
    USHORT                  GetDInterval_3() const              { return nDInterval3; }
    USHORT                  GetTInterval_1() const              { return nTInterval1; }
    const Time&             GetTime_1() const                   { return aTime1; }
    const Time&             GetTime_2() const                   { return aTime2; }

    void                    SetFrequencyMode(FrequencyMode eNew)    { eFrqMode = eNew; }
    void                    SetFrequencyTimeMode(FrequencyTimeMode eNew){ eFrqTimeMode = eNew; }
    void                    SetDInterval_1(USHORT nNew)             { nDInterval1 = nNew; }
    void                    SetDInterval_2(USHORT nNew)             { nDInterval2 = nNew; }
    void                    SetDInterval_3(USHORT nNew)             { nDInterval3 = nNew; }
    void                    SetTInterval_1(USHORT nNew)             { nTInterval1 = nNew; }
    void                    SetTime_1(const Time& rNew)             { aTime1 = rNew; }
    void                    SetTime_2(const Time& rNew)             { aTime2 = rNew; }
};

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.2.320); FILE MERGED 2008/04/01 15:44:29 thb 1.2.320.2: #i85898# Stripping all external header guards 2008/03/31 13:01:03 rt 1.2.320.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: frqitem.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _FRQITEM_HXX
#define _FRQITEM_HXX

#include <tools/rtti.hxx>
#include <tools/time.hxx>
#include <tools/datetime.hxx>
#include <tools/string.hxx>

#include <svtools/poolitem.hxx>

class SvStream;

DBG_NAMEEX(SfxFrequencyItem)

// class SfxFrequencyItem -------------------------------------------------

///////////////////////////////////////////////////////////////////////////////
/*
FRQ_DAILY
    * jeden X'ten Tag
    nInterval1 = 1 .. 999

    * jeden Wochentag
    nInterval1 = USHRT_MAX

FRQ_WEEKLY
    + wiederhole jede X'te Woche
    nInterval1 = 1 .. 99

    + an SU, MO, TU, WE, TH, FR, SA
    nInterval2 = WD_SUNDAY | WD_MONDAY | WD_TUESDAY | WD_WEDNESDAY |
                 WD_THURSDAY | WD_FRIDAY | WD_SATURDAY

FRQ_MONTHLY_DAILY
    * jeden X'ten Tag von jedem X'ten Monat
    nInterval1 = 1 .. 31
    nInterval2 = 1 .. 6

FRQ_MONTHLY_LOGIC
    * jeden ersten, zweiten, dritten, vierten oder letzten Wochentag jeden X'ten Monats
    nInterval1 = 0 .. 4
    nInterval2 = WD_SUNDAY | WD_MONDAY | WD_TUESDAY | WD_WEDNESDAY |
                 WD_THURSDAY | WD_FRIDAY | WD_SATURDAY
    nInterval3 = 1 .. 6

===============================================================================

FRQ_TIME_AT
    * Update um Uhrzeit
    nTime1 = 00:00:00 - 24:00:00

FRQ_TIME_REPEAT
    * Wiederhole alle X Stunden
    nTInterval1 = 1 .. 8
        + zwischen Uhrzeit 1 und 2
        nTime1 = 00:00:00 - 24:00:00
        nTime2 = 00:00:00 - 24:00:00

*/
///////////////////////////////////////////////////////////////////////////////

enum FrequencyMode
{
    FRQ_DAILY               = 1,
    FRQ_WEEKLY              = 2,
    FRQ_MONTHLY_DAILY       = 3,
    FRQ_MONTHLY_LOGIC       = 4
};

enum FrequencyTimeMode
{
    FRQ_TIME_AT             = 1,
    FRQ_TIME_REPEAT         = 2,
    FRQ_TIME_REPEAT_RANGE   = 3
};

#define WD_SUNDAY       0x0001
#define WD_MONDAY       0x0002
#define WD_TUESDAY      0x0004
#define WD_WEDNESDAY    0x0008
#define WD_THURSDAY     0x0010
#define WD_FRIDAY       0x0020
#define WD_SATURDAY     0x0040

class SfxFrequencyItem : public SfxPoolItem
{
private:
            FrequencyMode       eFrqMode;
            FrequencyTimeMode   eFrqTimeMode;

            USHORT              nDInterval1;
            USHORT              nDInterval2;
            USHORT              nDInterval3;

            USHORT              nTInterval1;
            Time                aTime1;
            Time                aTime2;

            BOOL                bMissingDate;
            DateTime            aMissingDate;

            Time                _CalcTime( BOOL bForToday ) const;
public:
            TYPEINFO();

            SfxFrequencyItem( const SfxFrequencyItem& rCpy );
            SfxFrequencyItem( USHORT nWhich );
            SfxFrequencyItem( USHORT nWhich, FrequencyMode eMode, FrequencyTimeMode eTMode,
                              USHORT nDI1, USHORT nDI2, USHORT nDI3, USHORT nTI1,
                              const Time& rT1, const Time& rT2 );
            ~SfxFrequencyItem() { DBG_DTOR(SfxFrequencyItem, 0); }

    virtual int             operator==( const SfxPoolItem& )            const;
    using SfxPoolItem::Compare;
    virtual int             Compare( const SfxPoolItem &rWith )         const;
    virtual SfxPoolItem*    Create( SvStream&, USHORT nItemVersion )    const;
    virtual SvStream&       Store( SvStream&, USHORT nItemVersion )     const;
    virtual SfxPoolItem*    Clone( SfxItemPool* pPool = 0 )             const;
    virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres,
                                SfxMapUnit eCoreMetric, SfxMapUnit ePresMetric, XubString &rText,
                                const IntlWrapper * = 0 ) const;

    DateTime                CalcNextTick( const DateTime& rNow, BOOL bFirst = FALSE );

    BOOL                    HasMissingDate() const              { return bMissingDate; }
    DateTime                GetMissingDate() const              { return aMissingDate; }

    FrequencyMode           GetFrequencyMode() const            { return eFrqMode; }
    FrequencyTimeMode       GetFrequencyTimeMode() const        { return eFrqTimeMode; }
    USHORT                  GetDInterval_1() const              { return nDInterval1; }
    USHORT                  GetDInterval_2() const              { return nDInterval2; }
    USHORT                  GetDInterval_3() const              { return nDInterval3; }
    USHORT                  GetTInterval_1() const              { return nTInterval1; }
    const Time&             GetTime_1() const                   { return aTime1; }
    const Time&             GetTime_2() const                   { return aTime2; }

    void                    SetFrequencyMode(FrequencyMode eNew)    { eFrqMode = eNew; }
    void                    SetFrequencyTimeMode(FrequencyTimeMode eNew){ eFrqTimeMode = eNew; }
    void                    SetDInterval_1(USHORT nNew)             { nDInterval1 = nNew; }
    void                    SetDInterval_2(USHORT nNew)             { nDInterval2 = nNew; }
    void                    SetDInterval_3(USHORT nNew)             { nDInterval3 = nNew; }
    void                    SetTInterval_1(USHORT nNew)             { nTInterval1 = nNew; }
    void                    SetTime_1(const Time& rNew)             { aTime1 = rNew; }
    void                    SetTime_2(const Time& rNew)             { aTime2 = rNew; }
};

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: nfversi.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-04-11 19:29:09 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef NF_NFVERSI_HXX
#define NF_NFVERSI_HXX

//      file ID's

#define SV_NUMBERFORMATTER_VERSION_SYSTORE      0x0004
#define SV_NUMBERFORMATTER_VERSION_KEYWORDS     0x0005
#define SV_NUMBERFORMATTER_VERSION_NEWSTANDARD  0x0006
#define SV_NUMBERFORMATTER_VERSION_NF_TIME_HH_MMSS00    0x0007
#define SV_NUMBERFORMATTER_VERSION_NF_DATE_WW   0x0008
#define SV_NUMBERFORMATTER_VERSION_NEW_CURR     0x0009
#define SV_NUMBERFORMATTER_VERSION_YEAR2000     0x000a
#define SV_NUMBERFORMATTER_VERSION_TWODIGITYEAR 0x000b
#define SV_NUMBERFORMATTER_VERSION_NF_DATETIME_SYS_DDMMYYYY_HHMMSS  0x000c
#define SV_NUMBERFORMATTER_VERSION_CALENDAR     0x000d
#define SV_NUMBERFORMATTER_VERSION_ADDITIONAL_I18N_FORMATS  0x000e

#define SV_NUMBERFORMATTER_VERSION              0x000e

// 1 bis 18.01.96
// 2 ab  19.01.96, TT.MM.JJJJ dazu
// 3 ab  13.02.96 (nicht emergency) #.##0,00 CCC dazu
// 4 ab  30.07.97 364i speichern, was SYSTEM wirklich war (vorhandenes
//                  Dummy-Feld wird benutzt, keine File-Format Aenderung)
// 5 ab  07.08.97 nicht-deutsch ist nicht immer englisch
//                  aeltere nicht-deutsche benutzerdefinierte Formate onLoad
//                  konvertieren
// 6 ab  17.10.97 neu: Keyword NNN fuer langen Wochentag ohne Separator,
//                  wird in aelteren Versionen nicht ausgewertet!
//                  Neue Standard Datumformate, DIN etc.
// 7 ab  25.05.98 StandardFormat [HH]:MM:SS,00 (NF_TIME_HH_MMSS00) fuer
//                  automatische Eingabe-Erkennung von 100stel Sekunden mit Stunden
// 8 ab  19.06.98 StandardFormat WW (NF_DATE_WW) fuer Kalenderwoche
// 9 ab  17.12.98 neue Waehrungsformate [$DM-xxx]
// A ab  25.01.99 Year2000 speichern/laden
// B ab  12.02.99 Year2000 ist allgemeines TwoDigitYearStart
// C     ??.??.?? date/time format of system variables
// D     23.11.00 new calendar
// E     19.01.01 additional formats provided by i18n

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.2.320); FILE MERGED 2008/03/31 13:01:06 rt 1.2.320.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: nfversi.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef NF_NFVERSI_HXX
#define NF_NFVERSI_HXX

//      file ID's

#define SV_NUMBERFORMATTER_VERSION_SYSTORE      0x0004
#define SV_NUMBERFORMATTER_VERSION_KEYWORDS     0x0005
#define SV_NUMBERFORMATTER_VERSION_NEWSTANDARD  0x0006
#define SV_NUMBERFORMATTER_VERSION_NF_TIME_HH_MMSS00    0x0007
#define SV_NUMBERFORMATTER_VERSION_NF_DATE_WW   0x0008
#define SV_NUMBERFORMATTER_VERSION_NEW_CURR     0x0009
#define SV_NUMBERFORMATTER_VERSION_YEAR2000     0x000a
#define SV_NUMBERFORMATTER_VERSION_TWODIGITYEAR 0x000b
#define SV_NUMBERFORMATTER_VERSION_NF_DATETIME_SYS_DDMMYYYY_HHMMSS  0x000c
#define SV_NUMBERFORMATTER_VERSION_CALENDAR     0x000d
#define SV_NUMBERFORMATTER_VERSION_ADDITIONAL_I18N_FORMATS  0x000e

#define SV_NUMBERFORMATTER_VERSION              0x000e

// 1 bis 18.01.96
// 2 ab  19.01.96, TT.MM.JJJJ dazu
// 3 ab  13.02.96 (nicht emergency) #.##0,00 CCC dazu
// 4 ab  30.07.97 364i speichern, was SYSTEM wirklich war (vorhandenes
//                  Dummy-Feld wird benutzt, keine File-Format Aenderung)
// 5 ab  07.08.97 nicht-deutsch ist nicht immer englisch
//                  aeltere nicht-deutsche benutzerdefinierte Formate onLoad
//                  konvertieren
// 6 ab  17.10.97 neu: Keyword NNN fuer langen Wochentag ohne Separator,
//                  wird in aelteren Versionen nicht ausgewertet!
//                  Neue Standard Datumformate, DIN etc.
// 7 ab  25.05.98 StandardFormat [HH]:MM:SS,00 (NF_TIME_HH_MMSS00) fuer
//                  automatische Eingabe-Erkennung von 100stel Sekunden mit Stunden
// 8 ab  19.06.98 StandardFormat WW (NF_DATE_WW) fuer Kalenderwoche
// 9 ab  17.12.98 neue Waehrungsformate [$DM-xxx]
// A ab  25.01.99 Year2000 speichern/laden
// B ab  12.02.99 Year2000 ist allgemeines TwoDigitYearStart
// C     ??.??.?? date/time format of system variables
// D     23.11.00 new calendar
// E     19.01.01 additional formats provided by i18n

#endif

<|endoftext|>