<commit_before>/*
 * AdamicAdarDistance.cpp
 *
 *  Created on: 18.11.2014
 *      Author: Michael Hamann, Gerd Lindner
 */

#include "AdamicAdarDistance.h"
#include "../auxiliary/Log.h"
#include "../auxiliary/Timer.h"

namespace NetworKit {

AdamicAdarDistance::AdamicAdarDistance(const Graph& G) : NodeDistance(G) {
}

void AdamicAdarDistance::preprocess() {
	Graph g = G;

	//Node attribute: marker
	std::vector<bool> nodeMarker(g.upperNodeIdBound(), false);

	//Edge attribute: triangle count
	aaDistance = std::vector<double>(g.upperEdgeIdBound(), 0);

	g.forNodes([&](node u) {
		//Mark all neighbors
		g.forNeighborsOf(u, [&](node v) {
			nodeMarker[v] = true;
		});

		//For all neighbors: check for already marked neighbors.
		g.forNeighborsOf(u, [&](node _u, node v, edgeid eid_uv) {
			g.forNeighborsOf(v, [&](node _v, node w, edgeid eid_vw) {
				if (nodeMarker[w]) {

					edgeid eid_uw = G.edgeId(u, w);

					aaDistance[eid_uv] = aaDistance[eid_uv] + 1.0 / log(g.degree(w));
					aaDistance[eid_uw] = aaDistance[eid_uw] + 1.0 / log(g.degree(v));
					aaDistance[eid_vw] = aaDistance[eid_vw] + 1.0 / log(g.degree(u));
				}
			});

			nodeMarker[v] = false;
		});

		removeNode(g, u);
	});

	//TODO: invert aaDistance.
}

double AdamicAdarDistance::distance(node u, node v) {
	edgeid eid = G.edgeId(u, v);
	return aaDistance[eid];
}

std::vector< double > AdamicAdarDistance::getEdgeAttribute() {
	return aaDistance;
}

void AdamicAdarDistance::removeNode(Graph& graph, node u) {
	//isolate the node before removing it.
	graph.forNeighborsOf(u, [&](node v) {
		graph.removeEdge(u,v);
	});

	graph.removeNode(u);
}

} /* namespace NetworKit */
<commit_msg>AdamicAdar now computes Distance instead of Similarity<commit_after>/*
 * AdamicAdarDistance.cpp
 *
 *  Created on: 18.11.2014
 *      Author: Michael Hamann, Gerd Lindner
 */

#include "AdamicAdarDistance.h"
#include "../auxiliary/Log.h"
#include "../auxiliary/Timer.h"

namespace NetworKit {

AdamicAdarDistance::AdamicAdarDistance(const Graph& G) : NodeDistance(G) {
}

void AdamicAdarDistance::preprocess() {
	Graph g = G;

	//Node attribute: marker
	std::vector<bool> nodeMarker(g.upperNodeIdBound(), false);

	//Edge attribute: triangle count
	aaDistance = std::vector<double>(g.upperEdgeIdBound(), 0);

	g.forNodes([&](node u) {
		//Mark all neighbors
		g.forNeighborsOf(u, [&](node v) {
			nodeMarker[v] = true;
		});

		//For all neighbors: check for already marked neighbors.
		g.forNeighborsOf(u, [&](node _u, node v, edgeid eid_uv) {
			g.forNeighborsOf(v, [&](node _v, node w, edgeid eid_vw) {
				if (nodeMarker[w]) {

					edgeid eid_uw = G.edgeId(u, w);

					aaDistance[eid_uv] = aaDistance[eid_uv] + 1.0 / log(g.degree(w));
					aaDistance[eid_uw] = aaDistance[eid_uw] + 1.0 / log(g.degree(v));
					aaDistance[eid_vw] = aaDistance[eid_vw] + 1.0 / log(g.degree(u));
				}
			});

			nodeMarker[v] = false;
		});

		removeNode(g, u);
	});

	G.parallelForEdges([&](node u, node v, edgeid eid) {
		aaDistance[eid] = 1 / aaDistance[eid];
	});
}

double AdamicAdarDistance::distance(node u, node v) {
	edgeid eid = G.edgeId(u, v);
	return aaDistance[eid];
}

std::vector< double > AdamicAdarDistance::getEdgeAttribute() {
	return aaDistance;
}

void AdamicAdarDistance::removeNode(Graph& graph, node u) {
	//isolate the node before removing it.
	graph.forNeighborsOf(u, [&](node v) {
		graph.removeEdge(u,v);
	});

	graph.removeNode(u);
}

} /* namespace NetworKit */
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2016 nyorain
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#pragma once

#ifndef NYTL_INCLUDE_RANGE_HPP
#define NYTL_INCLUDE_RANGE_HPP

#include <cstdlib>
#include <stdexcept>

namespace nytl
{

namespace detail { template<typename T, typename C, typename = void> struct ValidContainer; }

///The Range class represents a part of a non-owned contigous sequence.
///Can be useful to pass mulitple parameters (without size limitations) to a function.
///Does not allocate any additional memory on the heap since it simply references the
///sequence it was constructed with. Therefore one must assure that the sequence will live longer
///than the Range object.
///Alternative names: span, array_view
template<typename T>
class Range
{
public:
	using Value = std::remove_const_t<T>;
	using Pointer = Value*;
	using ConstPointer = const Value*;
	using Reference = Value&;
	using ConstReference = const Value&;
	using Size = std::size_t;
	using Iterator = ConstPointer;
	using ConstIterator = ConstPointer;
	using ReverseIterator = std::reverse_iterator<Iterator>;
	using ConstReverseIterator = std::reverse_iterator<ConstIterator>;

	using value_type = Value;
	using pointer = Pointer;
	using const_pointer = ConstPointer;
	using reference = Reference;
	using const_reference = ConstReference;
	using iterator = Iterator;
	using const_iterator = ConstIterator;
	using reverse_iterator = ReverseIterator;
	using const_reverse_iterator = ConstReverseIterator;
	using size_type = Size;
	using difference_type = std::ptrdiff_t;

public:
	constexpr Range() noexcept = default;
	constexpr Range(std::nullptr_t, std::size_t = 0) noexcept : data_(nullptr), size_(0) {}
	constexpr Range(const T& value, std::size_t size) noexcept : data_(&value), size_(size) {}
	constexpr Range(const T* value, std::size_t size) noexcept : data_(value), size_(size) {}
	template<std::size_t N> constexpr Range(const T (&arr)[N]) noexcept : data_(arr), size_(N) {}

	constexpr Range(const std::initializer_list<T>& list) noexcept
		: data_(list.begin()), size_(list.size()) {}

	template<typename C, typename = typename detail::ValidContainer<T, C>::type>
	Range(const C& con) noexcept : data_(&(*con.begin())), size_(con.end() - con.begin()) {}

	constexpr ConstPointer data() const noexcept { return data_; }
	constexpr std::size_t size() const noexcept { return size_; }
	constexpr bool empty() const noexcept { return size() == 0; }
	constexpr Size max_size() const noexcept { return size(); }

	constexpr Iterator begin() const noexcept { return data_; }
	constexpr Iterator end() const noexcept { return data_ + size_; }

	constexpr ConstIterator cbegin() const noexcept { return data_; }
	constexpr ConstIterator cend() const noexcept { return data_ + size_; }

	constexpr ReverseIterator rbegin() const noexcept { return {end()}; }
	constexpr ReverseIterator rend() const noexcept { return {begin()}; }

	constexpr ConstReverseIterator crbegin() const noexcept { return {cend()}; }
	constexpr ConstReverseIterator crend() const noexcept { return {cbegin()}; }

	constexpr ConstReference operator[](Size i) const noexcept { return *(data_ + i); }
	constexpr ConstReference at(Size i) const
		{ if(i >= size_) throw std::out_of_range("Range::at"); return data_[i]; }

	constexpr ConstReference front() const noexcept { return *data_; }
	constexpr ConstReference back() const noexcept { return *(data_ + size_); }

	constexpr Range<T> slice(Size pos, Size size) const noexcept { return{data_ + pos, size}; }

	///\{
	///Those function can be used to copy the range to an owned container.
	///range.as<std::vector>() will convert into an vector of the range type (T).
	///range.as<std::vector<float>>() will convert into an float-vector (if possible).
	template<typename C> C as() const { return C(data_, data_ + size_); }
	template<template<class...> typename C> C<T> as() const { return C<T>(data_, data_ + size_); }
	///\}

protected:
	ConstPointer data_ = nullptr;
	Size size_ = 0;
};

///\{
///Utility functions for easily constructing a range object.
///Only needed until c++17.
template<typename T>
Range<T> constexpr makeRange(const T& value, std::size_t size){ return {value, size}; }

template<template<class...> typename C, typename T, typename... TA> Range<T>
makeRange(const C<T, TA...>& container){ return Range<T>(container); }

template<typename T, std::size_t N> Range<T>
makeRange(const T (&array)[N]) { return Range<T>(array); }
///\}

namespace detail
{

template<typename T, typename C>
struct ValidContainer<T, C,
	typename std::enable_if<
		std::is_convertible<
			decltype(*std::declval<C>().begin()),
			const T&
		>::value &&
		std::is_convertible<
			decltype(std::declval<C>().end() - std::declval<C>().begin()),
			std::size_t
		>::value
	>::type
> { using type = void; };

}

}

#endif //header guard
<commit_msg>range fixes<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2016 nyorain
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#pragma once

#ifndef NYTL_INCLUDE_RANGE_HPP
#define NYTL_INCLUDE_RANGE_HPP

#include <cstdlib>
#include <stdexcept>

#include <vector>
#include <string>
#include <array>

namespace nytl
{

namespace detail { template<typename T, typename C, typename = void> struct ValidContainer; }

///The Range class represents a part of a non-owned contigous sequence.
///Can be useful to pass mulitple parameters (without size limitations) to a function.
///Does not allocate any additional memory on the heap since it simply references the
///sequence it was constructed with. Therefore one must assure that the sequence will live longer
///than the Range object.
///Alternative names: span, array_view
template<typename T>
class Range
{
public:
	using Value = std::remove_const_t<T>;
	using Pointer = Value*;
	using ConstPointer = const Value*;
	using Reference = Value&;
	using ConstReference = const Value&;
	using Size = std::size_t;
	using Iterator = ConstPointer;
	using ConstIterator = ConstPointer;
	using ReverseIterator = std::reverse_iterator<Iterator>;
	using ConstReverseIterator = std::reverse_iterator<ConstIterator>;

	using value_type = Value;
	using pointer = Pointer;
	using const_pointer = ConstPointer;
	using reference = Reference;
	using const_reference = ConstReference;
	using iterator = Iterator;
	using const_iterator = ConstIterator;
	using reverse_iterator = ReverseIterator;
	using const_reverse_iterator = ConstReverseIterator;
	using size_type = Size;
	using difference_type = std::ptrdiff_t;

public:
	constexpr Range() noexcept = default;
	constexpr Range(std::nullptr_t, std::size_t = 0) noexcept : data_(nullptr), size_(0) {}
	constexpr Range(const T& value, std::size_t size) noexcept : data_(&value), size_(size) {}
	constexpr Range(const T* value, std::size_t size) noexcept : data_(value), size_(size) {}

	template<std::size_t N> constexpr Range(const T (&arr)[N]) noexcept : data_(arr), size_(N) {}
	template<std::size_t N> Range(const std::array<T, N>& o) noexcept : data_(o.data()), size_(N) {}

	Range(const std::vector<T>& vector) noexcept : data_(vector.data()), size_(vector.size()) {}
	Range(const std::basic_string<T>& str) noexcept : data_(str.data()), size_(str.size()) {}

	constexpr Range(const std::initializer_list<T>& list) noexcept
		: data_(list.begin()), size_(list.size()) {}

	constexpr ConstPointer data() const noexcept { return data_; }
	constexpr std::size_t size() const noexcept { return size_; }
	constexpr bool empty() const noexcept { return size() == 0; }
	constexpr Size max_size() const noexcept { return size(); }

	constexpr Iterator begin() const noexcept { return data_; }
	constexpr Iterator end() const noexcept { return data_ + size_; }

	constexpr ConstIterator cbegin() const noexcept { return data_; }
	constexpr ConstIterator cend() const noexcept { return data_ + size_; }

	constexpr ReverseIterator rbegin() const noexcept { return {end()}; }
	constexpr ReverseIterator rend() const noexcept { return {begin()}; }

	constexpr ConstReverseIterator crbegin() const noexcept { return {cend()}; }
	constexpr ConstReverseIterator crend() const noexcept { return {cbegin()}; }

	constexpr ConstReference operator[](Size i) const noexcept { return *(data_ + i); }
	constexpr ConstReference at(Size i) const
		{ if(i >= size_) throw std::out_of_range("Range::at"); return data_[i]; }

	constexpr ConstReference front() const noexcept { return *data_; }
	constexpr ConstReference back() const noexcept { return *(data_ + size_); }

	constexpr Range<T> slice(Size pos, Size size) const noexcept { return{data_ + pos, size}; }

	///\{
	///Those function can be used to copy the range to an owned container.
	///range.as<std::vector>() will convert into an vector of the range type (T).
	///range.as<std::vector<float>>() will convert into an float-vector (if possible).
	template<typename C> C as() const { return C(data_, data_ + size_); }
	template<template<class...> typename C> C<T> as() const { return C<T>(data_, data_ + size_); }
	///\}

protected:
	ConstPointer data_ = nullptr;
	Size size_ = 0;
};

///\{
///Utility functions for easily constructing a range object.
///Only needed until c++17.
template<typename T>
Range<T> constexpr makeRange(const T& value, std::size_t size){ return {value, size}; }

template<template<class...> typename C, typename T, typename... TA> Range<T>
makeRange(const C<T, TA...>& container){ return Range<T>(container); }

template<typename T, std::size_t N> Range<T>
makeRange(const T (&array)[N]) { return Range<T>(array); }
///\}

}

#endif //header guard
<|endoftext|>


<commit_before>#include	<cstdlib>
#include	<cmath>
#include	<fstream>
#include	<sstream>
#include	<iostream>
#include	<iomanip>
#include	<string>
#include	<vector>
#include	<algorithm>
#include	<exception>
#include	<sys/time.h>
#include	"modules/htmTree.h"
#include	"modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
	//// Initializations ---------------------------------------------
	srand48(1234); // Make sure we have reproducability
	check_args(argc);
	Time t, time; // t for global, time for local
	init_time(t);
	Feat F;

	// Read parameters file //
	F.readInputFile(argv[1]);
	printFile(argv[1]);
	// Read galaxies
	Gals G;
    if(F.Ascii){
        G=read_galaxies_ascii(F);}
    else{
        G = read_galaxies(F);
    }
	F.Ngal = G.size();
	printf("# Read %s galaxies from %s \n",f(F.Ngal).c_str(),F.galFile.c_str());
    std::vector<int> count;
    count=count_galaxies(G);
    printf(" Number of galaxies by type, QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF\n");
    for(int i=0;i<8;i++){printf (" type %d number  %d  \n",i, count[i]);}
    // make MTL
    //MTL Min=make_MTL(G,F);
    //write_MTLfile(Min);
    MTL M=read_MTLfile(F);
    assign_priority_class(M);
    //find available SS and SF galaxies on each petal

    std::vector <int> count_class(M.priority_list.size(),0);

    printf("Number in each priority class.  The last two are SF and SS.\n");
    for(int i;i<M.size();++i){
        count_class[M[i].priority_class]+=1;
    }
    for(int i;i<M.priority_list.size();++i){
        printf("  class  %d  number  %d\n",i,count_class[i]);
    }

    printf(" number of MTL galaxies  %d\n",M.size());

	PP pp;
	pp.read_fiber_positions(F);
	F.Nfiber = pp.fp.size()/2;
	F.Npetal = max(pp.spectrom)+1;
    F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
	pp.get_neighbors(F); pp.compute_fibsofsp(F);
	Plates P = read_plate_centers(F);
    F.Nplate=P.size();
	printf("# Read %s plate centers from %s and %d fibers from %s\n",f(F.Nplate).c_str(),F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

	// Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
	F.cb = create_cb(); // cb=central body
	F.fh = create_fh(); // fh=fiber holder

	//// Collect available galaxies <-> tilefibers --------------------
	// HTM Tree of galaxies
	const double MinTreeSize = 0.01;
	init_time_at(time,"# Start building HTM tree",t);
	htmTree<struct target> T(M,MinTreeSize);
	print_time(time,"# ... took :");//T.stats();

	// For plates/fibers, collect available galaxies; done in parallel  P[plate j].av_gal[k]=[g1,g2,..]
	collect_galaxies_for_all(M,T,P,pp,F);

	// For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
	collect_available_tilefibers(M,P,F);

	//results_on_inputs("doc/figs/",G,P,F,true);

	//// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
	Assignment A(M,F);
	print_time(t,"# Start assignment at : ");

	// Make a plan ----------------------------------------------------
	//new_assign_fibers(G,P,pp,F,A); // Plans whole survey without sky fibers, standard stars
                                   // assumes maximum number of observations needed for QSOs, LRGs
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.Nplate, F.Ngal, F.Nfiber);

    simple_assign(M,P,pp,F,A);
    diagnostic(M,G,F,A);
    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs
                                    // Want to have even distribution of unused fibers
                                    // so we can put in sky fibers and standard stars

	// Smooth out distribution of free fibers, and increase the number of assignments

	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);// more iterations will improve performance slightly
	for (int i=0; i<1; i++) {                           // more iterations will improve performance slightly
		improve(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
	}
	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);

	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);
    //try assigning SF and SS before real time assignment
    for (int j=0;j<F.Nplate;++j){
        A.next_plate=j;
        assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF just before an observation
        assign_unused(j,M,P,pp,F,A);
    }
    init_time_at(time,"# Begin real time assignment",t);

	// Still not updated, so all QSO targets have multiple observations etc
	// Apply and update the plan --------------------------------------
    //int pass_intervals[6] {0,500,1000,2000,4000,F.Nplate};
    printf(" pass_intervals  %d %d %d %d %d\n",F.pass_intervals[0],F.pass_intervals[1],F.pass_intervals[2],F.pass_intervals[3],F.pass_intervals[4]);

    for(int i=0;i<F.pass_intervals.size();++i){
        printf(" before pass = %d  at %d  tiles\n",i,F.pass_intervals[i]);
        //display_results("doc/figs/",G,P,pp,F,A,true);
        A.next_plate=F.pass_intervals[i];
        for (int jj=F.pass_intervals[i]; jj<F.Nplate; jj++) {
            int j = A.next_plate;
            printf(" - Plate %d :\n",j);
            //printf(" %s not as - ",format(5,f(A.unused_f(j,F))).c_str()); fl();
            assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF just before an observation

            assign_unused(j,M,P,pp,F,A);

            A.next_plate++;
        }

        A.next_plate=F.pass_intervals[i];
        for (int jj=F.pass_intervals[i]; jj<F.pass_intervals[i+1]&&jj<F.Nplate; jj++) {
            int j = A.next_plate;

            // Update corrects all future occurrences of wrong QSOs etc and tries to observe something else
            if (0<=j-F.Analysis) update_plan_from_one_obs(G,M,P,pp,F,A,F.Nplate-1); else printf("\n");
            A.next_plate++;
        }
        if(A.next_plate<F.Nplate){
        redistribute_tf(M,P,pp,F,A);
        redistribute_tf(M,P,pp,F,A);
        improve(M,P,pp,F,A);
        redistribute_tf(M,P,pp,F,A);
        }
    }
/*
	init_time_at(time,"# Begin real time assignment",t);
	for (int jj=0; jj<F.Nplate; jj++) {
		int j = A.next_plate;

		if(j%1000==0)diagnostic(M,G,F,A);
        assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF just before an observation
		assign_unused(j,M,P,pp,F,A);
		//if (j%2000==0) pyplotTile(j,"doc/figs",G,P,pp,F,A); // Picture of positioners, galaxies

		if (0<=j-F.Analysis) update_plan_from_one_obs(G,M,P,pp,F,A,F.Nplate-1); else printf("\n");
		A.next_plate++;
		// Redistribute and improve on various occasions  add more times if desired

		if ( j==1000 || j==3000) {
            printf ( "Redistribute and improve at j = %d\n",j);
			redistribute_tf(M,P,pp,F,A);
			redistribute_tf(M,P,pp,F,A);
			improve(M,P,pp,F,A);
			redistribute_tf(M,P,pp,F,A);
            //diagnostic(M,G,F,A);
		}

    }
	print_time(time,"# ... took :");*/

    //diagnostic check on SS and SF
    /*
    for (int j=0;j<F.Nplate;++j){
        for (int p=0; p<F.Npetal; ++p){
            if(P[j].SS_in_petal[p]!=F.MaxSS){printf("SS j= %d p= %d number = %d\n",j,p,P[j].SS_in_petal[p]);}
            if(P[j].SF_in_petal[p]!=F.MaxSF){printf("SF j= %d p= %d number = %d\n",j,p,P[j].SF_in_petal[p]);}
        }
    }
*/
	// Results -------------------------------------------------------
    if (F.Output) for (int j=0; j<F.Nplate; j++){
        write_FAtile_ascii(j,F.outDir,M,P,pp,F,A);
    }
    if (F.Output) for (int j=0; j<F.Nplate; j++){
        fa_write(j,F.outDir,M,P,pp,F,A); // Write output
    }

	display_results("doc/figs/",G,M,P,pp,F,A,true);
	if (F.Verif) A.verif(P,M,pp,F); // Verification that the assignment is sane

	print_time(t,"# Finished !... in");

	return(0);

}
<commit_msg>remove printf<commit_after>#include	<cstdlib>
#include	<cmath>
#include	<fstream>
#include	<sstream>
#include	<iostream>
#include	<iomanip>
#include	<string>
#include	<vector>
#include	<algorithm>
#include	<exception>
#include	<sys/time.h>
#include	"modules/htmTree.h"
#include	"modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
	//// Initializations ---------------------------------------------
	srand48(1234); // Make sure we have reproducability
	check_args(argc);
	Time t, time; // t for global, time for local
	init_time(t);
	Feat F;

	// Read parameters file //
	F.readInputFile(argv[1]);
	printFile(argv[1]);
	// Read galaxies
	Gals G;
    if(F.Ascii){
        G=read_galaxies_ascii(F);}
    else{
        G = read_galaxies(F);
    }
	F.Ngal = G.size();
	printf("# Read %s galaxies from %s \n",f(F.Ngal).c_str(),F.galFile.c_str());
    std::vector<int> count;
    count=count_galaxies(G);
    printf(" Number of galaxies by type, QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF\n");
    for(int i=0;i<8;i++){printf (" type %d number  %d  \n",i, count[i]);}
    // make MTL
    //MTL Min=make_MTL(G,F);
    //write_MTLfile(Min);
    MTL M=read_MTLfile(F);
    assign_priority_class(M);
    //find available SS and SF galaxies on each petal

    std::vector <int> count_class(M.priority_list.size(),0);

    printf("Number in each priority class.  The last two are SF and SS.\n");
    for(int i;i<M.size();++i){
        count_class[M[i].priority_class]+=1;
    }
    for(int i;i<M.priority_list.size();++i){
        printf("  class  %d  number  %d\n",i,count_class[i]);
    }

    printf(" number of MTL galaxies  %d\n",M.size());

	PP pp;
	pp.read_fiber_positions(F);
	F.Nfiber = pp.fp.size()/2;
	F.Npetal = max(pp.spectrom)+1;
    F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
	pp.get_neighbors(F); pp.compute_fibsofsp(F);
	Plates P = read_plate_centers(F);
    F.Nplate=P.size();
	printf("# Read %s plate centers from %s and %d fibers from %s\n",f(F.Nplate).c_str(),F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

	// Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
	F.cb = create_cb(); // cb=central body
	F.fh = create_fh(); // fh=fiber holder

	//// Collect available galaxies <-> tilefibers --------------------
	// HTM Tree of galaxies
	const double MinTreeSize = 0.01;
	init_time_at(time,"# Start building HTM tree",t);
	htmTree<struct target> T(M,MinTreeSize);
	print_time(time,"# ... took :");//T.stats();

	// For plates/fibers, collect available galaxies; done in parallel  P[plate j].av_gal[k]=[g1,g2,..]
	collect_galaxies_for_all(M,T,P,pp,F);

	// For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
	collect_available_tilefibers(M,P,F);

	//results_on_inputs("doc/figs/",G,P,F,true);

	//// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
	Assignment A(M,F);
	print_time(t,"# Start assignment at : ");

	// Make a plan ----------------------------------------------------
	//new_assign_fibers(G,P,pp,F,A); // Plans whole survey without sky fibers, standard stars
                                   // assumes maximum number of observations needed for QSOs, LRGs
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.Nplate, F.Ngal, F.Nfiber);

    simple_assign(M,P,pp,F,A);
    diagnostic(M,G,F,A);
    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs
                                    // Want to have even distribution of unused fibers
                                    // so we can put in sky fibers and standard stars

	// Smooth out distribution of free fibers, and increase the number of assignments

	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);// more iterations will improve performance slightly
	for (int i=0; i<1; i++) {                           // more iterations will improve performance slightly
		improve(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
	}
	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);

	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);
    //try assigning SF and SS before real time assignment
    for (int j=0;j<F.Nplate;++j){
        A.next_plate=j;
        assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF just before an observation
        assign_unused(j,M,P,pp,F,A);
    }
    init_time_at(time,"# Begin real time assignment",t);

	// Still not updated, so all QSO targets have multiple observations etc
	// Apply and update the plan --------------------------------------
    //int pass_intervals[6] {0,500,1000,2000,4000,F.Nplate};
    printf(" pass_intervals  %d %d %d %d %d\n",F.pass_intervals[0],F.pass_intervals[1],F.pass_intervals[2],F.pass_intervals[3],F.pass_intervals[4]);

    for(int i=0;i<F.pass_intervals.size();++i){
        printf(" before pass = %d  at %d  tiles\n",i,F.pass_intervals[i]);
        //display_results("doc/figs/",G,P,pp,F,A,true);
        A.next_plate=F.pass_intervals[i];
        for (int jj=F.pass_intervals[i]; jj<F.Nplate; jj++) {
            int j = A.next_plate;
            //printf(" - Plate %d :\n",j);
            //printf(" %s not as - ",format(5,f(A.unused_f(j,F))).c_str()); fl();
            assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF just before an observation

            assign_unused(j,M,P,pp,F,A);

            A.next_plate++;
        }

        A.next_plate=F.pass_intervals[i];
        for (int jj=F.pass_intervals[i]; jj<F.pass_intervals[i+1]&&jj<F.Nplate; jj++) {
            int j = A.next_plate;

            // Update corrects all future occurrences of wrong QSOs etc and tries to observe something else
            if (0<=j-F.Analysis) update_plan_from_one_obs(G,M,P,pp,F,A,F.Nplate-1); else printf("\n");
            A.next_plate++;
        }
        if(A.next_plate<F.Nplate){
        redistribute_tf(M,P,pp,F,A);
        redistribute_tf(M,P,pp,F,A);
        improve(M,P,pp,F,A);
        redistribute_tf(M,P,pp,F,A);
        }
    }
/*
	init_time_at(time,"# Begin real time assignment",t);
	for (int jj=0; jj<F.Nplate; jj++) {
		int j = A.next_plate;

		if(j%1000==0)diagnostic(M,G,F,A);
        assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF just before an observation
		assign_unused(j,M,P,pp,F,A);
		//if (j%2000==0) pyplotTile(j,"doc/figs",G,P,pp,F,A); // Picture of positioners, galaxies

		if (0<=j-F.Analysis) update_plan_from_one_obs(G,M,P,pp,F,A,F.Nplate-1); else printf("\n");
		A.next_plate++;
		// Redistribute and improve on various occasions  add more times if desired

		if ( j==1000 || j==3000) {
            printf ( "Redistribute and improve at j = %d\n",j);
			redistribute_tf(M,P,pp,F,A);
			redistribute_tf(M,P,pp,F,A);
			improve(M,P,pp,F,A);
			redistribute_tf(M,P,pp,F,A);
            //diagnostic(M,G,F,A);
		}

    }
	print_time(time,"# ... took :");*/

    //diagnostic check on SS and SF
    /*
    for (int j=0;j<F.Nplate;++j){
        for (int p=0; p<F.Npetal; ++p){
            if(P[j].SS_in_petal[p]!=F.MaxSS){printf("SS j= %d p= %d number = %d\n",j,p,P[j].SS_in_petal[p]);}
            if(P[j].SF_in_petal[p]!=F.MaxSF){printf("SF j= %d p= %d number = %d\n",j,p,P[j].SF_in_petal[p]);}
        }
    }
*/
	// Results -------------------------------------------------------
    if (F.Output) for (int j=0; j<F.Nplate; j++){
        write_FAtile_ascii(j,F.outDir,M,P,pp,F,A);
    }
    if (F.Output) for (int j=0; j<F.Nplate; j++){
        fa_write(j,F.outDir,M,P,pp,F,A); // Write output
    }

	display_results("doc/figs/",G,M,P,pp,F,A,true);
	if (F.Verif) A.verif(P,M,pp,F); // Verification that the assignment is sane

	print_time(t,"# Finished !... in");

	return(0);

}
<|endoftext|>


<commit_before>#ifndef DICE_PARSER_HPP_
#define DICE_PARSER_HPP_

#include <memory>
#include <string>
#include <vector>
#include <ostream>
#include <functional>
#include <unordered_map>

#include "logger.hpp"
#include "value.hpp"
#include "lexer.hpp"
#include "environment.hpp"
#include "random_variable.hpp"

namespace dice
{
    // dice expression parser
    template<typename Lexer, typename Logger, typename Environment>
    class parser
    {
    public:
        using value_type = std::unique_ptr<base_value>;

        parser(Lexer* reader, Logger* log, Environment* env) :
            lexer_(reader),
            log_(log),
            env_(env) {}

        /** Parse expression provided by the lexer.
         * Operators are left associative unless stated otherwise.
         * List of operators (from lowest to highest precedence):
         * -#  <, <=, !=, ==, >=, >, in (relational operators, not assosiative)
         * -#  + (add), - (subtract)
         * -#  * (multiply), / (divide)
         * -#  - (unary minus)
         * -#  D|d (roll dice)
         * @return calculated value
         */
        value_type parse()
        {
            lookahead_ = lexer_->read_token();

            // When using the expr as a start production, don't add
            // the whole FOLLOW(expr) to the synchronizing tokens.
            // Use just the end symbol
            while (lookahead_.type != token_type::end && !in_first_expr())
            {
                error("Invalid token at the beginning of an expression: " +
                    to_string(lookahead_));
                eat(lookahead_.type);
            }

            if (in_first_expr())
            {
                auto result = expr();
                // make sure we've processed the whole expression
                eat(token_type::end);
                return result;
            }
            return make<type_int>(0);
        }

    private:
        Lexer* lexer_;
        Logger* log_;
        Environment* env_;
        token lookahead_;

        value_type expr()
        {
            auto left = add();
            if (lookahead_.type == token_type::in)
            {
                eat(token_type::in);
                eat(token_type::left_square_bracket);

                // parse lower bound of the interval
                if (!check_add())
                {
                    error("Invalid operand for the lower bound of operator in");
                    return left;
                }
                auto lower_bound = add();

                eat(token_type::param_delim);

                // parse upper bound of the interval
                if (!check_add())
                {
                    error("Invalid operand for the upper bound of operator in");
                    return left;
                }
                auto upper_bound = add();

                eat(token_type::right_square_bracket);

                return env_->call("in",
                    std::move(left),
                    std::move(lower_bound),
                    std::move(upper_bound));
            }
            else if (lookahead_.type == token_type::rel_op)
            {
                auto op = lookahead_;
                eat(token_type::rel_op);
                auto right = add();

                // calculate the value
                return env_->call(op.value, std::move(left), std::move(right));
            }
            return left;
        }

        value_type add()
        {
            std::string op;
            auto result = mult();
            for (;;)
            {
                // decide on the next operation
                if (lookahead_.type == token_type::add)
                {
                    eat(token_type::add);
                    op = "+";
                }
                else if (lookahead_.type == token_type::sub)
                {
                    eat(token_type::sub);
                    op = "-";
                }
                else
                {
                    break;
                }

                // compute the operator if there won't be any parse error
                if (check_mult())
                {
                    result = env_->call(op, std::move(result), mult());
                }
                else // otherwise, ignore the operator
                {
                    error("Invalid operand for binary operator " + op);
                }
            }
            return result;
        }

        value_type mult()
        {
            std::string op;
            auto result = dice_roll();
            for (;;)
            {
                // decide on the next operation
                if (lookahead_.type == token_type::mult)
                {
                    eat(token_type::mult);
                    op = "*";
                }
                else if (lookahead_.type == token_type::div)
                {
                    eat(token_type::div);
                    op = "/";
                }
                else
                {
                    break;
                }

                // compute the operation if there won't be any parse error
                if (check_dice_roll())
                {
                    result = env_->call(op, std::move(result), dice_roll());
                }
                else // otherwise, ignore the operator
                {
                    error("Invalid operand for binary operator " + op);
                }
            }
            return result;
        }

        value_type dice_roll()
        {
            // determine the sign
            int count = 0;
            for (;;)
            {
                if (lookahead_.type == token_type::sub)
                {
                    eat(token_type::sub);
                    ++count;
                }
                else
                {
                    break;
                }
            }

            // parse dice roll
            auto result = factor();
            for (;;)
            {
                if (lookahead_.type == token_type::roll_op)
                {
                    eat(token_type::roll_op);

                    // only use the factor production if there won't be any parse error
                    if (check_factor())
                    {
                        result = env_->call("roll", std::move(result), factor());
                    }
                    else // otherwise, ignore the operator
                    {
                        error("Invalid operand for binary operator D (dice roll)");
                    }
                }
                else
                {
                    break;
                }
            }

            // add sign
            if (count % 2 != 0)
                result = env_->call("unary-", std::move(result));
            return result;
        }

        value_type factor()
        {
            if (lookahead_.type == token_type::left_parent)
            {
                eat(token_type::left_parent);
                auto result = expr();
                eat(token_type::right_parent);
                return result;
            }
            else if (lookahead_.type == token_type::number_int)
            {
                auto value = std::atoi(lookahead_.value.c_str());
                eat(lookahead_.type);
                return make<type_int>(std::move(value));
            }
            else if (lookahead_.type == token_type::number_fp)
            {
                auto value = std::atof(lookahead_.value.c_str());
                eat(lookahead_.type);
                return make<type_double>(std::move(value));
            }
            else if (lookahead_.type == token_type::id)
            {
                // parse a function call
                auto id = lookahead_;
                eat(token_type::id);
                eat(token_type::left_parent);
                auto args = param_list();
                eat(token_type::right_parent);

                return env_->call_var(id.value, args.begin(), args.end());
            }

            error("Expected " + to_string(token_type::left_parent) + ", " +
                to_string(token_type::number_int) + ", " +
                to_string(token_type::number_fp) + " or " +
                to_string(token_type::id) +  ", got " +
                to_string(lookahead_) + ".");
            return make<type_int>(0);
        }

        std::vector<value_type> param_list()
        {
            std::vector<value_type> args;
            if (lookahead_.type == token_type::right_parent)
            {
                return args; // no arguments
            }

            std::size_t number = 0;
            for (;;)
            {
                if (check_expr())
                {
                    args.emplace_back(expr());
                }
                else
                {
                    error("Invalid parameter " + std::to_string(number));
                }

                if (lookahead_.type != token_type::param_delim)
                {
                    break;
                }
                eat(token_type::param_delim);
                ++number;
            }
            return args;
        }

        // true <=> next token is in FIRST(expr)
        bool in_first_expr() const
        {
            return in_first_add();
        }

        // true <=> next token is in FIRST(add)
        bool in_first_add() const
        {
            return in_first_mult();
        }

        // true <=> next token is in FIRST(mult)
        bool in_first_mult() const
        {
            return in_first_dice_roll();
        }

        // true <=> next token is in FIRST(dice_roll)
        bool in_first_dice_roll() const
        {
            return lookahead_.type == token_type::sub ||
                in_first_factor();
        }

        // true <=> next token is in FIRST(factor)
        bool in_first_factor() const
        {
            return lookahead_.type == token_type::left_parent ||
                lookahead_.type == token_type::number_int ||
                lookahead_.type == token_type::number_fp ||
                lookahead_.type == token_type::id;
        }

        // true <=> next token is in FIRST(param_list)
        bool in_first_param_list() const
        {
            return lookahead_.type == token_type::right_parent ||
                in_first_expr();
        }

        // true <=> next token is in FOLLOW(expr)
        bool in_follow_expr() const
        {
            return lookahead_.type == token_type::end ||
                lookahead_.type == token_type::right_parent ||
                in_follow_param_list();
        }

        // true <=> next token is in FOLLOW(add)
        bool in_follow_add() const
        {
            return lookahead_.type == token_type::add ||
                lookahead_.type == token_type::sub ||
                lookahead_.type == token_type::in ||
                lookahead_.type == token_type::rel_op ||
                lookahead_.type == token_type::param_delim ||
                lookahead_.type == token_type::right_square_bracket ||
                in_follow_expr();
        }

        // true <=> next token is in FOLLOW(mult)
        bool in_follow_mult() const
        {
            return lookahead_.type == token_type::mult ||
                lookahead_.type == token_type::div ||
                in_follow_add();
        }

        // true <=> next token is in FOLLOW(dice_roll)
        bool in_follow_dice_roll() const
        {
            return lookahead_.type == token_type::roll_op ||
               in_follow_mult();
        }

        // true <=> next token is in FOLLOW(factor)
        bool in_follow_factor() const
        {
            return in_follow_dice_roll();
        }

        // true <=> next token is in FOLLOW(param_list)
        bool in_follow_param_list() const
        {
            return lookahead_.type == token_type::param_delim ||
                lookahead_.type == token_type::right_parent; // FOLLOW(opt_params)
        }

        bool check_expr()
        {
            while (!in_follow_expr() && !in_first_expr())
            {
                error("Invalid token at the beginning of an expression: " +
                    to_string(lookahead_));
                eat(lookahead_.type);
            }
            return in_first_expr();
        }

        bool check_add()
        {
            while (!in_first_add() && !in_follow_add())
            {
                error("Invalid token at the beginning of an addition: " +
                    to_string(lookahead_));
                eat(lookahead_.type);
            }
            return in_first_add();
        }

        bool check_mult()
        {
            while (!in_first_mult() && !in_follow_mult())
            {
                error("Invalid token at the beginning of a multiplication: " +
                    to_string(lookahead_));
                eat(lookahead_.type);
            }
            return in_first_mult();
        }

        bool check_dice_roll()
        {
            while (!in_first_dice_roll() && !in_follow_dice_roll())
            {
                error("Invalid token at the beginning of a dice roll: " +
                    to_string(lookahead_));
                eat(lookahead_.type);
            }
            return in_first_dice_roll();
        }

        bool check_factor()
        {
            while (!in_first_factor() && !in_follow_factor())
            {
                error("Invalid token at the beginning of a factor: " +
                    to_string(lookahead_));
                eat(lookahead_.type);
            }
            return in_first_factor();
        }

        bool check_param_list()
        {
            while (!in_first_param_list() && !in_follow_param_list())
            {
                error("Invalid token at the beginning of parameter list: " +
                    to_string(lookahead_));
                eat(lookahead_.type);
            }
            return in_first_param_list();
        }

        /** Read token of given type from the input.
         * If there is no such token, "add" it at current position.
         * New token is read into the lookahead_ variable.
         * @param expected type
         */
        void eat(token_type type)
        {
            if (lookahead_.type != type)
            {
                // report the error and "insert" the token (i.e. assume it's there)
                error("Expected " +
                    to_string(type) + ", got " +
                    to_string(lookahead_) + ".");
            }
            lookahead_ = lexer_->read_token();
        }

        /** Report a parsing error.
         * @param error message
         */
        void error(const std::string& message)
        {
            log_->error(
                lexer_->location().line,
                lexer_->location().col,
                message);
        }
    };
}

#endif // DICE_PARSER_HPP_<commit_msg>Graceful error handling for relational operators<commit_after>#ifndef DICE_PARSER_HPP_
#define DICE_PARSER_HPP_

#include <memory>
#include <string>
#include <vector>
#include <ostream>
#include <functional>
#include <unordered_map>

#include "logger.hpp"
#include "value.hpp"
#include "lexer.hpp"
#include "environment.hpp"
#include "random_variable.hpp"

namespace dice
{
    // dice expression parser
    template<typename Lexer, typename Logger, typename Environment>
    class parser
    {
    public:
        using value_type = std::unique_ptr<base_value>;

        parser(Lexer* reader, Logger* log, Environment* env) :
            lexer_(reader),
            log_(log),
            env_(env) {}

        /** Parse expression provided by the lexer.
         * Operators are left associative unless stated otherwise.
         * List of operators (from lowest to highest precedence):
         * -#  <, <=, !=, ==, >=, >, in (relational operators, not assosiative)
         * -#  + (add), - (subtract)
         * -#  * (multiply), / (divide)
         * -#  - (unary minus)
         * -#  D|d (roll dice)
         * @return calculated value
         */
        value_type parse()
        {
            lookahead_ = lexer_->read_token();

            // When using the expr as a start production, don't add
            // the whole FOLLOW(expr) to the synchronizing tokens.
            // Use just the end symbol
            while (lookahead_.type != token_type::end && !in_first_expr())
            {
                error("Invalid token at the beginning of an expression: " +
                    to_string(lookahead_));
                eat(lookahead_.type);
            }

            if (in_first_expr())
            {
                auto result = expr();
                // make sure we've processed the whole expression
                eat(token_type::end);
                return result;
            }
            return make<type_int>(0);
        }

    private:
        Lexer* lexer_;
        Logger* log_;
        Environment* env_;
        token lookahead_;

        value_type expr()
        {
            auto left = add();
            if (lookahead_.type == token_type::in)
            {
                eat(token_type::in);
                eat(token_type::left_square_bracket);

                // parse lower bound of the interval
                if (!check_add())
                {
                    error("Invalid operand for the lower bound of operator in");
                    return left;
                }
                auto lower_bound = add();

                eat(token_type::param_delim);

                // parse upper bound of the interval
                if (!check_add())
                {
                    error("Invalid operand for the upper bound of operator in");
                    return left;
                }
                auto upper_bound = add();

                eat(token_type::right_square_bracket);

                return env_->call("in",
                    std::move(left),
                    std::move(lower_bound),
                    std::move(upper_bound));
            }
            else if (lookahead_.type == token_type::rel_op)
            {
                auto op = lookahead_;
                eat(token_type::rel_op);
                if (check_add())
                {
                    auto right = add();
                    return env_->call(op.value, std::move(left), std::move(right));
                }
                else
                {
                    error("Invalid operand for binary operator " + to_string(op));
                }
            }
            return left;
        }

        value_type add()
        {
            std::string op;
            auto result = mult();
            for (;;)
            {
                // decide on the next operation
                if (lookahead_.type == token_type::add)
                {
                    eat(token_type::add);
                    op = "+";
                }
                else if (lookahead_.type == token_type::sub)
                {
                    eat(token_type::sub);
                    op = "-";
                }
                else
                {
                    break;
                }

                // compute the operator if there won't be any parse error
                if (check_mult())
                {
                    result = env_->call(op, std::move(result), mult());
                }
                else // otherwise, ignore the operator
                {
                    error("Invalid operand for binary operator " + op);
                }
            }
            return result;
        }

        value_type mult()
        {
            std::string op;
            auto result = dice_roll();
            for (;;)
            {
                // decide on the next operation
                if (lookahead_.type == token_type::mult)
                {
                    eat(token_type::mult);
                    op = "*";
                }
                else if (lookahead_.type == token_type::div)
                {
                    eat(token_type::div);
                    op = "/";
                }
                else
                {
                    break;
                }

                // compute the operation if there won't be any parse error
                if (check_dice_roll())
                {
                    result = env_->call(op, std::move(result), dice_roll());
                }
                else // otherwise, ignore the operator
                {
                    error("Invalid operand for binary operator " + op);
                }
            }
            return result;
        }

        value_type dice_roll()
        {
            // determine the sign
            int count = 0;
            for (;;)
            {
                if (lookahead_.type == token_type::sub)
                {
                    eat(token_type::sub);
                    ++count;
                }
                else
                {
                    break;
                }
            }

            // parse dice roll
            auto result = factor();
            for (;;)
            {
                if (lookahead_.type == token_type::roll_op)
                {
                    eat(token_type::roll_op);

                    // only use the factor production if there won't be any parse error
                    if (check_factor())
                    {
                        result = env_->call("roll", std::move(result), factor());
                    }
                    else // otherwise, ignore the operator
                    {
                        error("Invalid operand for binary operator D (dice roll)");
                    }
                }
                else
                {
                    break;
                }
            }

            // add sign
            if (count % 2 != 0)
                result = env_->call("unary-", std::move(result));
            return result;
        }

        value_type factor()
        {
            if (lookahead_.type == token_type::left_parent)
            {
                eat(token_type::left_parent);
                auto result = expr();
                eat(token_type::right_parent);
                return result;
            }
            else if (lookahead_.type == token_type::number_int)
            {
                auto value = std::atoi(lookahead_.value.c_str());
                eat(lookahead_.type);
                return make<type_int>(std::move(value));
            }
            else if (lookahead_.type == token_type::number_fp)
            {
                auto value = std::atof(lookahead_.value.c_str());
                eat(lookahead_.type);
                return make<type_double>(std::move(value));
            }
            else if (lookahead_.type == token_type::id)
            {
                // parse a function call
                auto id = lookahead_;
                eat(token_type::id);
                eat(token_type::left_parent);
                auto args = param_list();
                eat(token_type::right_parent);

                return env_->call_var(id.value, args.begin(), args.end());
            }

            error("Expected " + to_string(token_type::left_parent) + ", " +
                to_string(token_type::number_int) + ", " +
                to_string(token_type::number_fp) + " or " +
                to_string(token_type::id) +  ", got " +
                to_string(lookahead_) + ".");
            return make<type_int>(0);
        }

        std::vector<value_type> param_list()
        {
            std::vector<value_type> args;
            if (lookahead_.type == token_type::right_parent)
            {
                return args; // no arguments
            }

            std::size_t number = 0;
            for (;;)
            {
                if (check_expr())
                {
                    args.emplace_back(expr());
                }
                else
                {
                    error("Invalid parameter " + std::to_string(number));
                }

                if (lookahead_.type != token_type::param_delim)
                {
                    break;
                }
                eat(token_type::param_delim);
                ++number;
            }
            return args;
        }

        // true <=> next token is in FIRST(expr)
        bool in_first_expr() const
        {
            return in_first_add();
        }

        // true <=> next token is in FIRST(add)
        bool in_first_add() const
        {
            return in_first_mult();
        }

        // true <=> next token is in FIRST(mult)
        bool in_first_mult() const
        {
            return in_first_dice_roll();
        }

        // true <=> next token is in FIRST(dice_roll)
        bool in_first_dice_roll() const
        {
            return lookahead_.type == token_type::sub ||
                in_first_factor();
        }

        // true <=> next token is in FIRST(factor)
        bool in_first_factor() const
        {
            return lookahead_.type == token_type::left_parent ||
                lookahead_.type == token_type::number_int ||
                lookahead_.type == token_type::number_fp ||
                lookahead_.type == token_type::id;
        }

        // true <=> next token is in FIRST(param_list)
        bool in_first_param_list() const
        {
            return lookahead_.type == token_type::right_parent ||
                in_first_expr();
        }

        // true <=> next token is in FOLLOW(expr)
        bool in_follow_expr() const
        {
            return lookahead_.type == token_type::end ||
                lookahead_.type == token_type::right_parent ||
                in_follow_param_list();
        }

        // true <=> next token is in FOLLOW(add)
        bool in_follow_add() const
        {
            return lookahead_.type == token_type::add ||
                lookahead_.type == token_type::sub ||
                lookahead_.type == token_type::in ||
                lookahead_.type == token_type::rel_op ||
                lookahead_.type == token_type::param_delim ||
                lookahead_.type == token_type::right_square_bracket ||
                in_follow_expr();
        }

        // true <=> next token is in FOLLOW(mult)
        bool in_follow_mult() const
        {
            return lookahead_.type == token_type::mult ||
                lookahead_.type == token_type::div ||
                in_follow_add();
        }

        // true <=> next token is in FOLLOW(dice_roll)
        bool in_follow_dice_roll() const
        {
            return lookahead_.type == token_type::roll_op ||
               in_follow_mult();
        }

        // true <=> next token is in FOLLOW(factor)
        bool in_follow_factor() const
        {
            return in_follow_dice_roll();
        }

        // true <=> next token is in FOLLOW(param_list)
        bool in_follow_param_list() const
        {
            return lookahead_.type == token_type::param_delim ||
                lookahead_.type == token_type::right_parent; // FOLLOW(opt_params)
        }

        bool check_expr()
        {
            while (!in_follow_expr() && !in_first_expr())
            {
                error("Invalid token at the beginning of an expression: " +
                    to_string(lookahead_));
                eat(lookahead_.type);
            }
            return in_first_expr();
        }

        bool check_add()
        {
            while (!in_first_add() && !in_follow_add())
            {
                error("Invalid token at the beginning of an addition: " +
                    to_string(lookahead_));
                eat(lookahead_.type);
            }
            return in_first_add();
        }

        bool check_mult()
        {
            while (!in_first_mult() && !in_follow_mult())
            {
                error("Invalid token at the beginning of a multiplication: " +
                    to_string(lookahead_));
                eat(lookahead_.type);
            }
            return in_first_mult();
        }

        bool check_dice_roll()
        {
            while (!in_first_dice_roll() && !in_follow_dice_roll())
            {
                error("Invalid token at the beginning of a dice roll: " +
                    to_string(lookahead_));
                eat(lookahead_.type);
            }
            return in_first_dice_roll();
        }

        bool check_factor()
        {
            while (!in_first_factor() && !in_follow_factor())
            {
                error("Invalid token at the beginning of a factor: " +
                    to_string(lookahead_));
                eat(lookahead_.type);
            }
            return in_first_factor();
        }

        bool check_param_list()
        {
            while (!in_first_param_list() && !in_follow_param_list())
            {
                error("Invalid token at the beginning of parameter list: " +
                    to_string(lookahead_));
                eat(lookahead_.type);
            }
            return in_first_param_list();
        }

        /** Read token of given type from the input.
         * If there is no such token, "add" it at current position.
         * New token is read into the lookahead_ variable.
         * @param expected type
         */
        void eat(token_type type)
        {
            if (lookahead_.type != type)
            {
                // report the error and "insert" the token (i.e. assume it's there)
                error("Expected " +
                    to_string(type) + ", got " +
                    to_string(lookahead_) + ".");
            }
            lookahead_ = lexer_->read_token();
        }

        /** Report a parsing error.
         * @param error message
         */
        void error(const std::string& message)
        {
            log_->error(
                lexer_->location().line,
                lexer_->location().col,
                message);
        }
    };
}

#endif // DICE_PARSER_HPP_<|endoftext|>


<commit_before>#include	<cstdlib>
#include	<cmath>
#include	<fstream>
#include	<sstream>
#include	<iostream>
#include	<iomanip>
#include	<string>
#include	<vector>
#include	<algorithm>
#include	<exception>
#include	<sys/time.h>
#include	"modules/htmTree.h"
#include	"modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
	//// Initializations ---------------------------------------------
	srand48(1234); // Make sure we have reproducability
	check_args(argc);
	Time t, time; // t for global, time for local
	init_time(t);
	Feat F;
    MTL M;

	// Read parameters file //
	F.readInputFile(argv[1]);
	printFile(argv[1]);
	// Read galaxies
    /*
	Gals G;
    if(F.Ascii){
        G=read_galaxies_ascii(F);}
    else{
        G = read_galaxies(F);
    }
	F.Ngal = G.size();
     */

    // Secret contains the identity of each target: QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF
    Gals Secret;
    printf("# Read %s galaxies from %s \n",f(F.Ngal).c_str(),F.Secretfile.c_str());
    Secret=read_Secretfile(F.Secretfile,F);
    F.Ngal= Secret.size();

    std::vector<int> count;
    count=count_galaxies(Secret);
    printf(" Number of galaxies by type, QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF\n");
    for(int i=0;i<8;i++){printf (" type %d number  %d  \n",i, count[i]);}
    //read the three input files
    MTL Targ=read_MTLfile(F.Targfile,F,0,0);
    MTL SStars=read_MTLfile(F.SStarsfile,F,1,0);
    MTL SkyF=read_MTLfile(F.SkyFfile,F,0,1);
    //combine the three input files

    M=Targ;

    printf(" M size %d \n",M.size());
    M.insert(M.end(),SStars.begin(),SStars.end());
    printf(" M size %d \n",M.size());
    M.insert(M.end(),SkyF.begin(),SkyF.end());
    printf(" M size %d \n",M.size());

    assign_priority_class(Targ);

    //establish priority classes
    std::vector <int> count_class(Targ.priority_list.size(),0);
    printf("Number in each priority class.  The last two are SF and SS.\n");
    for(int i;i<Targ.size();++i){
        count_class[Targ[i].priority_class]+=1;
    }
    for(int i;i<Targ.priority_list.size();++i){
        printf("  class  %d  number  %d\n",i,count_class[i]);
    }

    PP pp;
	pp.read_fiber_positions(F);
	F.Nfiber = pp.fp.size()/2;
	F.Npetal = max(pp.spectrom)+1;
    F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
	pp.get_neighbors(F); pp.compute_fibsofsp(F);
	Plates OP = read_plate_centers(F);
    Plates P;
    printf(" future plates %d\n",P.size());
    F.ONplate=OP.size();
	printf("# Read %s plate centers from %s and %d fibers from %s\n",f(F.ONplate).c_str(),F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

	// Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
	F.cb = create_cb(); // cb=central body
	F.fh = create_fh(); // fh=fiber holder

	//// Collect available galaxies <-> tilefibers --------------------
	// HTM Tree of galaxies
	const double MinTreeSize = 0.01;
	init_time_at(time,"# Start building HTM tree",t);
	htmTree<struct target> T(M,MinTreeSize);
	print_time(time,"# ... took :");//T.stats();

	// For plates/fibers, collect available galaxies; done in parallel
    collect_galaxies_for_all(M,T,OP,pp,F);

	// For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
	collect_available_tilefibers(M,OP,F);

	//results_on_inputs("doc/figs/",G,P,F,true);

	//// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.ONplate, F.Ngal, F.Nfiber);
    Assignment A(M,F);

	print_time(t,"# Start assignment at : ");

	// Make a plan ----------------------------------------------------
    // Plans whole survey without sky fibers, standard stars
    // assumes maximum number of observations needed for QSOs, LRGs

    simple_assign(M,OP,pp,F,A);

    //check to see if there are tiles with no galaxies
    //need to keep mapping of old tile list to new tile list
    for (int j=0;j<F.ONplate ;++j){
        bool not_done=true;
        for(int k=0;k<F.Nfiber && not_done;++k){
            if(A.TF[j][k]!=-1){
                 P.push_back(OP[j]);
                A.suborder.push_back(j);
                not_done=false;
            }
        }
    }
    F.Nplate=P.size();
    printf(" Plates after screening %d \n",F.Nplate);
    //if(F.diagnose)diagnostic(M,G,F,A);
    //diagnostic
    for (int j=0;j<F.Nplate;++j){
        for (int k=0;k<F.Nfiber;++k){
            if(k%50==0){
                int g=A.TF[A.suborder[j]][k];
                if(g!=-1){
                    dpair test_projection=projection(g,j,M,P);
                    if (test_projection.f>500. || test_projection.s>500.){
                        printf(" g %d  j %d test_projection.f  %f test_projection.s  %f\n",g,j,test_projection.f,test_projection.s);
                    }
                }
            }
        }
    }

    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs

	// Smooth out distribution of free fibers, and increase the number of assignments

	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);// more iterations will improve performance slightly
	for (int i=0; i<1; i++) {
        improve(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
	}

	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);
    //try assigning SF and SS before real time assignment
    for (int j=0;j<F.Nplate;++j){
        int js=A.suborder[j];
        A.next_plate=js;
        assign_sf_ss(js,M,P,pp,F,A); // Assign SS and SF for each tile
        assign_unused(js,M,P,pp,F,A);
    }

    init_time_at(time,"# Begin real time assignment",t);

	//Execute plan, updating targets at intervals

    for(int i=0;i<F.pass_intervals.size()&&F.pass_intervals[i]<F.Nplate;++i){
        printf(" before pass = %d  at %d  tiles\n",i,F.pass_intervals[i]);
        //display_results("doc/figs/",G,P,pp,F,A,true);
        //execute this phase (i) of survey
        //A.next_plate=F.pass_intervals[i];
        for (int jj=F.pass_intervals[i]; jj<F.Nplate; jj++) {
            int j = A.suborder[A.next_plate];
            printf("  next plate is %d \n",j);
            assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF
            assign_unused(j,M,P,pp,F,A);
            //A.next_plate++;
        }
        //update target information for this interval
        //A.next_plate=F.pass_intervals[i];
        for (int jj=F.pass_intervals[i]; jj<F.pass_intervals[i+1]&&jj<F.Nplate; jj++) {
            //int j = A.suborder[A.next_plate];
            int js=A.suborder[jj];
            // Update corrects all future occurrences of wrong QSOs etc and tries to observe something else
            if (0<=js-F.Analysis) update_plan_from_one_obs(Secret,M,P,pp,F,A,F.Nplate-1); else printf("\n");
            //A.next_plate++;
        }
        /*
        if(A.next_plate<F.Nplate){
        redistribute_tf(M,P,pp,F,A);
        redistribute_tf(M,P,pp,F,A);
        improve(M,P,pp,F,A);
        redistribute_tf(M,P,pp,F,A);
        }
         */
        if(F.diagnose)diagnostic(M,Secret,F,A);
    }

	// Results -------------------------------------------------------
    if (F.PrintAscii) for (int j=0; j<F.Nplate; j++){
        write_FAtile_ascii(j,F.outDir,M,P,pp,F,A);
    }

    if (F.PrintFits) for (int j=0; j<F.Nplate; j++){
        fa_write(j,F.outDir,M,P,pp,F,A); // Write output
    }

	display_results("doc/figs/",Secret,M,P,pp,F,A,true);
	if (F.Verif) A.verif(P,M,pp,F); // Verification that the assignment is sane

	print_time(t,"# Finished !... in");

	return(0);

}
<commit_msg>new diagnostic<commit_after>#include	<cstdlib>
#include	<cmath>
#include	<fstream>
#include	<sstream>
#include	<iostream>
#include	<iomanip>
#include	<string>
#include	<vector>
#include	<algorithm>
#include	<exception>
#include	<sys/time.h>
#include	"modules/htmTree.h"
#include	"modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
	//// Initializations ---------------------------------------------
	srand48(1234); // Make sure we have reproducability
	check_args(argc);
	Time t, time; // t for global, time for local
	init_time(t);
	Feat F;
    MTL M;

	// Read parameters file //
	F.readInputFile(argv[1]);
	printFile(argv[1]);
	// Read galaxies
    /*
	Gals G;
    if(F.Ascii){
        G=read_galaxies_ascii(F);}
    else{
        G = read_galaxies(F);
    }
	F.Ngal = G.size();
     */

    // Secret contains the identity of each target: QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF
    Gals Secret;
    printf("# Read %s galaxies from %s \n",f(F.Ngal).c_str(),F.Secretfile.c_str());
    Secret=read_Secretfile(F.Secretfile,F);
    F.Ngal= Secret.size();

    std::vector<int> count;
    count=count_galaxies(Secret);
    printf(" Number of galaxies by type, QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF\n");
    for(int i=0;i<8;i++){printf (" type %d number  %d  \n",i, count[i]);}
    //read the three input files
    MTL Targ=read_MTLfile(F.Targfile,F,0,0);
    MTL SStars=read_MTLfile(F.SStarsfile,F,1,0);
    MTL SkyF=read_MTLfile(F.SkyFfile,F,0,1);
    //combine the three input files

    M=Targ;

    printf(" M size %d \n",M.size());
    M.insert(M.end(),SStars.begin(),SStars.end());
    printf(" M size %d \n",M.size());
    M.insert(M.end(),SkyF.begin(),SkyF.end());
    printf(" M size %d \n",M.size());

    assign_priority_class(Targ);

    //establish priority classes
    std::vector <int> count_class(Targ.priority_list.size(),0);
    printf("Number in each priority class.  The last two are SF and SS.\n");
    for(int i;i<Targ.size();++i){
        count_class[Targ[i].priority_class]+=1;
    }
    for(int i;i<Targ.priority_list.size();++i){
        printf("  class  %d  number  %d\n",i,count_class[i]);
    }

    PP pp;
	pp.read_fiber_positions(F);
	F.Nfiber = pp.fp.size()/2;
	F.Npetal = max(pp.spectrom)+1;
    F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
	pp.get_neighbors(F); pp.compute_fibsofsp(F);
	Plates OP = read_plate_centers(F);
    Plates P;
    printf(" future plates %d\n",P.size());
    F.ONplate=OP.size();
	printf("# Read %s plate centers from %s and %d fibers from %s\n",f(F.ONplate).c_str(),F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

	// Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
	F.cb = create_cb(); // cb=central body
	F.fh = create_fh(); // fh=fiber holder

	//// Collect available galaxies <-> tilefibers --------------------
	// HTM Tree of galaxies
	const double MinTreeSize = 0.01;
	init_time_at(time,"# Start building HTM tree",t);
	htmTree<struct target> T(M,MinTreeSize);
	print_time(time,"# ... took :");//T.stats();

	// For plates/fibers, collect available galaxies; done in parallel
    collect_galaxies_for_all(M,T,OP,pp,F);

	// For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
	collect_available_tilefibers(M,OP,F);

	//results_on_inputs("doc/figs/",G,P,F,true);

	//// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.ONplate, F.Ngal, F.Nfiber);
    Assignment A(M,F);

	print_time(t,"# Start assignment at : ");

	// Make a plan ----------------------------------------------------
    // Plans whole survey without sky fibers, standard stars
    // assumes maximum number of observations needed for QSOs, LRGs

    simple_assign(M,OP,pp,F,A);

    //check to see if there are tiles with no galaxies
    //need to keep mapping of old tile list to new tile list
    for (int j=0;j<F.ONplate ;++j){
        bool not_done=true;
        for(int k=0;k<F.Nfiber && not_done;++k){
            if(A.TF[j][k]!=-1){
                 P.push_back(OP[j]);
                A.suborder.push_back(j);
                not_done=false;
            }
        }
    }
    F.Nplate=P.size();
    printf(" Plates after screening %d \n",F.Nplate);
    //if(F.diagnose)diagnostic(M,G,F,A);
    //diagnostic
    for (int j=0;j<F.Nplate;++j){
        js=A.suborder[j];
        printf(" j %d  js  %d\ ",j,js);
        for (int k=0;k<F.Nfiber;++k){
            if(k%1==0){
                int g=A.TF[js][k];
                if(g!=-1){
                    dpair test_projection=projection(g,j,M,P);
                    if (test_projection.f>500. || test_projection.s>500.){
                        printf(" g %d  j %d test_projection.f  %f test_projection.s  %f\n",g,j,test_projection.f,test_projection.s);
                    }
                }
            }
        }
    }

    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs

	// Smooth out distribution of free fibers, and increase the number of assignments

	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);// more iterations will improve performance slightly
	for (int i=0; i<1; i++) {
        improve(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
	}

	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);
    //try assigning SF and SS before real time assignment
    for (int j=0;j<F.Nplate;++j){
        int js=A.suborder[j];
        A.next_plate=js;
        assign_sf_ss(js,M,P,pp,F,A); // Assign SS and SF for each tile
        assign_unused(js,M,P,pp,F,A);
    }

    init_time_at(time,"# Begin real time assignment",t);

	//Execute plan, updating targets at intervals

    for(int i=0;i<F.pass_intervals.size()&&F.pass_intervals[i]<F.Nplate;++i){
        printf(" before pass = %d  at %d  tiles\n",i,F.pass_intervals[i]);
        //display_results("doc/figs/",G,P,pp,F,A,true);
        //execute this phase (i) of survey
        //A.next_plate=F.pass_intervals[i];
        for (int jj=F.pass_intervals[i]; jj<F.Nplate; jj++) {
            int j = A.suborder[A.next_plate];
            printf("  next plate is %d \n",j);
            assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF
            assign_unused(j,M,P,pp,F,A);
            //A.next_plate++;
        }
        //update target information for this interval
        //A.next_plate=F.pass_intervals[i];
        for (int jj=F.pass_intervals[i]; jj<F.pass_intervals[i+1]&&jj<F.Nplate; jj++) {
            //int j = A.suborder[A.next_plate];
            int js=A.suborder[jj];
            // Update corrects all future occurrences of wrong QSOs etc and tries to observe something else
            if (0<=js-F.Analysis) update_plan_from_one_obs(Secret,M,P,pp,F,A,F.Nplate-1); else printf("\n");
            //A.next_plate++;
        }
        /*
        if(A.next_plate<F.Nplate){
        redistribute_tf(M,P,pp,F,A);
        redistribute_tf(M,P,pp,F,A);
        improve(M,P,pp,F,A);
        redistribute_tf(M,P,pp,F,A);
        }
         */
        if(F.diagnose)diagnostic(M,Secret,F,A);
    }

	// Results -------------------------------------------------------
    if (F.PrintAscii) for (int j=0; j<F.Nplate; j++){
        write_FAtile_ascii(j,F.outDir,M,P,pp,F,A);
    }

    if (F.PrintFits) for (int j=0; j<F.Nplate; j++){
        fa_write(j,F.outDir,M,P,pp,F,A); // Write output
    }

	display_results("doc/figs/",Secret,M,P,pp,F,A,true);
	if (F.Verif) A.verif(P,M,pp,F); // Verification that the assignment is sane

	print_time(t,"# Finished !... in");

	return(0);

}
<|endoftext|>


<commit_before>// Copyright 2021 The Google Research Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#if GOOGLE_CUDA
#include <cusparse.h>

#include <unordered_map>

#include "sparse/ops/cc/common.h"

namespace sgk {

namespace {

using HandleMap = std::unordered_map<cudaStream_t, cusparseHandle_t>;

// Get singleton map of cuda streams to cusparse handles.
HandleMap* GetHandleMap() {
  static HandleMap handle_map;
  return &handle_map;
}

}  // namespace

cusparseHandle_t GetHandleForStream(cudaStream_t stream) {
  HandleMap* handle_map = GetHandleMap();
  auto it = handle_map->find(stream);
  if (it == handle_map->end()) {
    // Allocate new cusparse handle and set the stream.
    cusparseHandle_t new_handle;
    CUSPARSE_CALL(cusparseCreate(&new_handle));
    CUSPARSE_CALL(cusparseSetStream(new_handle, stream));
    it = handle_map->insert(std::make_pair(stream, new_handle)).first;
  }
  return it->second;
}

}  // namespace sgk
#endif  // GOOGLE_CUDA
<commit_msg>Internal change<commit_after>// Copyright 2021 The Google Research Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#if GOOGLE_CUDA
#include <cusparse.h>

#include <unordered_map>

#include "absl/container/flat_hash_map.h"
#include "sparse/ops/cc/common.h"

namespace sgk {

namespace {

using HandleMap = absl::flat_hash_map<cudaStream_t, cusparseHandle_t>;

// Get singleton map of cuda streams to cusparse handles.
HandleMap* GetHandleMap() {
  static HandleMap handle_map;
  return &handle_map;
}

}  // namespace

cusparseHandle_t GetHandleForStream(cudaStream_t stream) {
  HandleMap* handle_map = GetHandleMap();
  auto it = handle_map->find(stream);
  if (it == handle_map->end()) {
    // Allocate new cusparse handle and set the stream.
    cusparseHandle_t new_handle;
    CUSPARSE_CALL(cusparseCreate(&new_handle));
    CUSPARSE_CALL(cusparseSetStream(new_handle, stream));
    it = handle_map->insert(std::make_pair(stream, new_handle)).first;
  }
  return it->second;
}

}  // namespace sgk
#endif  // GOOGLE_CUDA
<|endoftext|>


<commit_before>#if PIXIE_WINDOWS

#include <exception>
#include <SDL.h>
#include <cstdio>
#include <cstdlib>
#include <thread>
#include <chrono>
#include "global/core/igniter.hpp"
#include "global/core/program.hpp"
#include "global/core/test_runner.hpp"

#if PIXIE_IS_TESTER_BUILD

int main(int argc, char * argv[])
{
    engine::test_runner_t runner;

    runner.run_test(argc, argv);
    runner.wait_till_completed();

    return runner.get_return_code();
}

#else

int main(int argc, char * argv[])
{
    BEGIN_PLATFORM_CONFIGURATION(windows)

    PLATFORM_ALLOWS_POLICIES(instances_application, multiple, single)
    PLATFORM_ALLOWS_POLICIES(instances_program, single)
    PLATFORM_ALLOWS_POLICIES(renderer_thread, detached)

    ALL_GLOBAL_COMPONENTS_BY_DEFAULT_ARE(enabled)

    USE_PROVIDER_FOR(config, config_storage)
    USE_PROVIDERS_FOR(config_changed, messenger, logger)
    USE_PROVIDER_FOR(config_storage, windows_registry)
    USE_PROVIDER_FOR(filesystem, windows)
    USE_PROVIDERS_FOR(logger, console, temp_file)
    USE_PROVIDERS_FOR(accountable_thread, messenger)
    USE_PROVIDER_FOR(thread_stats, windows)
    USE_PROVIDERS_FOR(thread_accounter, console)
    USE_PROVIDER_FOR(profiler, remotery)

#if PIXIE_IS_DEBUG_BUILD
    USE_SETTINGS(config_t, debug)
#else
    USE_SETTINGS(config_t, release)
#endif
    USE_SETTINGS(config_storage_t, normal)

    END_PLATFORM_CONFIGURATION()

    std::shared_ptr<engine::program_t> program = windows.ignite_from_main(argc, argv);
    if(!program) return EXIT_FAILURE; // Failed to ignite (for example different instance is running)

    program->get_app_overseer()->wait_for_completion();
    return program->get_extinguisher()->get_return_code();
}

#endif
#endif<commit_msg>Added sample code for profiler testing<commit_after>#if PIXIE_WINDOWS

#include <exception>
#include <SDL.h>
#include <cstdio>
#include <cstdlib>
#include <thread>
#include <chrono>
#include "global/core/igniter.hpp"
#include "global/core/program.hpp"
#include "global/core/test_runner.hpp"

#if PIXIE_IS_TESTER_BUILD

int main(int argc, char * argv[])
{
    engine::test_runner_t runner;

    runner.run_test(argc, argv);
    runner.wait_till_completed();

    return runner.get_return_code();
}

#else

int main(int argc, char * argv[])
{
    BEGIN_PLATFORM_CONFIGURATION(windows)

    PLATFORM_ALLOWS_POLICIES(instances_application, multiple, single)
    PLATFORM_ALLOWS_POLICIES(instances_program, single)
    PLATFORM_ALLOWS_POLICIES(renderer_thread, detached)

    ALL_GLOBAL_COMPONENTS_BY_DEFAULT_ARE(enabled)

    USE_PROVIDER_FOR(config, config_storage)
    USE_PROVIDERS_FOR(config_changed, messenger, logger)
    USE_PROVIDER_FOR(config_storage, windows_registry)
    USE_PROVIDER_FOR(filesystem, windows)
    USE_PROVIDERS_FOR(logger, console, temp_file)
    USE_PROVIDERS_FOR(accountable_thread, messenger)
    USE_PROVIDER_FOR(thread_stats, windows)
    USE_PROVIDERS_FOR(thread_accounter, console)
    USE_PROVIDER_FOR(profiler, remotery)

#if PIXIE_IS_DEBUG_BUILD
    USE_SETTINGS(config_t, debug)
#else
    USE_SETTINGS(config_t, release)
#endif
    USE_SETTINGS(config_storage_t, normal)

    END_PLATFORM_CONFIGURATION()

    std::shared_ptr<engine::program_t> program = windows.ignite_from_main(argc, argv);
    if(!program) return EXIT_FAILURE; // Failed to ignite (for example different instance is running)
/*
    program->get_profiler()->name_current_thread("Main thread"_u);
    for(int i = 0; i < 1024; i++)
    {
        program->get_profiler()->prof_begin_section("Frame");
        for(int p = 0; p < 5; p++)
        {
            program->get_profiler()->prof_begin_section("Op 1");
            std::this_thread::sleep_for(std::chrono::milliseconds(30));
            program->get_profiler()->prof_end_section();
        }
        for(int p = 0; p < 3; p++)
        {
            program->get_profiler()->prof_begin_section("Op 2");
            std::this_thread::sleep_for(std::chrono::milliseconds(40));
            program->get_profiler()->prof_end_section();
        }
        for(int p = 0; p < 4; p++)
        {
            program->get_profiler()->prof_begin_section("Op 3");
            std::this_thread::sleep_for(std::chrono::milliseconds(45));
            program->get_profiler()->prof_end_section();
        }
        program->get_profiler()->prof_end_section();
    }
*/
    program->get_app_overseer()->wait_for_completion();
    return program->get_extinguisher()->get_return_code();
}

#endif
#endif<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fuslsel.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-12-14 17:17:12 $
 *
 *  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 SD_FU_SLIDE_SELECTION_HXX
#define SD_FU_SLIDE_SELECTION_HXX

#ifndef SD_FU_SLIDE_HXX
#include "fuslid.hxx"
#endif
#ifndef _LIST_HXX
#include <tools/list.hxx>
#endif

class SdDrawDocument;
class Sound;

namespace sd {

class SlideView;
class SlideViewShell;
class Window;

struct FSS_IsShowingEffectInfo
{
    BOOL bIsShowingEffect;          // TRUE while we show a fade effect one the slide view
    BOOL bDisposed;                 // TRUE if the FuSlideSelection was deleted during fade effect
};

class FuSlideSelection
    : public FuSlide
{
public:
    TYPEINFO();

    static FunctionReference Create( SlideViewShell* pViewSh, ::sd::Window* pWin, SlideView* pView, SdDrawDocument* pDoc, SfxRequest& rReq );
    virtual void DoExecute( SfxRequest& rReq );

    // Mouse- & Key-Events
    virtual BOOL                KeyInput(const KeyEvent& rKEvt);
    virtual BOOL                MouseMove(const MouseEvent& rMEvt);
    virtual BOOL                MouseButtonUp(const MouseEvent& rMEvt);
    virtual BOOL                MouseButtonDown(const MouseEvent& rMEvt);
    virtual void                Paint(const Rectangle& rRect, ::sd::Window* pWin);

    virtual void                Activate();        // Function aktivieren
    virtual void                Deactivate();          // Function deaktivieren

    virtual void                ScrollStart();
    virtual void                ScrollEnd();

    BOOL                        IsShowingEffect() const { return pIsShowingEffectInfo && pIsShowingEffectInfo->bIsShowingEffect; }

    /** is called when the currenct function should be aborted.

        This is used when a function gets a KEY_ESCAPE but can also
        be called directly.

        @returns true if a active function was aborted
    */
    virtual bool cancel();

protected:
    FuSlideSelection (
        SlideViewShell* pViewSh,
        ::sd::Window* pWin,
        SlideView* pView,
        SdDrawDocument* pDoc,
        SfxRequest& rReq);
    virtual ~FuSlideSelection (void);

private:
    BOOL                        bSubstShown;
    BOOL                        bPageHit;
    List                        aSubstList;       // Liste mit Ertsatzdarstellungen
    Point                       aDragPos;             // hier wird die Seite angefasst
    BOOL                        bDragSelection;
    Point                       aDragSelRectAnchor;  // fester Punkt des Selektionsrechtecks
    Rectangle                   aDragSelRect;
    Point                       aPosOfInsertMarker;
    Sound*                      pSound;
    FSS_IsShowingEffectInfo*    pIsShowingEffectInfo;

    void                        DrawInsertMarker(BOOL bShow);
    Point                       CalcPosOfInsertMarker(const Point& rPoint);

    USHORT                      GetTargetPage(const Point& rPoint) const;

    void                        CreateSubst();
    void                        DeleteSubst();
    void                        DrawSubst() const;
    void                        ChangeSubstPos(const Point& rVector);
    void                        DrawDragSelectionRect() const;
    void                        ShowEffect(USHORT nPageNo);

                                DECL_LINK( DragSlideHdl, Timer* );
};

} // end of namespace sd

#endif

<commit_msg>INTEGRATION: CWS unifysound01_DEV300 (1.7.442); FILE MERGED 2007/08/30 08:28:00 cmc 1.7.442.1: #i81144# move filepicker from vcl sound to avmedia sound<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fuslsel.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-07 16:27:21 $
 *
 *  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 SD_FU_SLIDE_SELECTION_HXX
#define SD_FU_SLIDE_SELECTION_HXX

#ifndef SD_FU_SLIDE_HXX
#include "fuslid.hxx"
#endif
#ifndef _LIST_HXX
#include <tools/list.hxx>
#endif

class SdDrawDocument;
class Sound;

namespace sd {

class SlideView;
class SlideViewShell;
class Window;

struct FSS_IsShowingEffectInfo
{
    BOOL bIsShowingEffect;          // TRUE while we show a fade effect one the slide view
    BOOL bDisposed;                 // TRUE if the FuSlideSelection was deleted during fade effect
};

class FuSlideSelection
    : public FuSlide
{
public:
    TYPEINFO();

    static FunctionReference Create( SlideViewShell* pViewSh, ::sd::Window* pWin, SlideView* pView, SdDrawDocument* pDoc, SfxRequest& rReq );
    virtual void DoExecute( SfxRequest& rReq );

    // Mouse- & Key-Events
    virtual BOOL                KeyInput(const KeyEvent& rKEvt);
    virtual BOOL                MouseMove(const MouseEvent& rMEvt);
    virtual BOOL                MouseButtonUp(const MouseEvent& rMEvt);
    virtual BOOL                MouseButtonDown(const MouseEvent& rMEvt);
    virtual void                Paint(const Rectangle& rRect, ::sd::Window* pWin);

    virtual void                Activate();        // Function aktivieren
    virtual void                Deactivate();          // Function deaktivieren

    virtual void                ScrollStart();
    virtual void                ScrollEnd();

    BOOL                        IsShowingEffect() const { return pIsShowingEffectInfo && pIsShowingEffectInfo->bIsShowingEffect; }

    /** is called when the currenct function should be aborted.

        This is used when a function gets a KEY_ESCAPE but can also
        be called directly.

        @returns true if a active function was aborted
    */
    virtual bool cancel();

protected:
    FuSlideSelection (
        SlideViewShell* pViewSh,
        ::sd::Window* pWin,
        SlideView* pView,
        SdDrawDocument* pDoc,
        SfxRequest& rReq);
    virtual ~FuSlideSelection (void);

private:
    BOOL                        bSubstShown;
    BOOL                        bPageHit;
    List                        aSubstList;       // Liste mit Ertsatzdarstellungen
    Point                       aDragPos;             // hier wird die Seite angefasst
    BOOL                        bDragSelection;
    Point                       aDragSelRectAnchor;  // fester Punkt des Selektionsrechtecks
    Rectangle                   aDragSelRect;
    Point                       aPosOfInsertMarker;
    FSS_IsShowingEffectInfo*    pIsShowingEffectInfo;

    void                        DrawInsertMarker(BOOL bShow);
    Point                       CalcPosOfInsertMarker(const Point& rPoint);

    USHORT                      GetTargetPage(const Point& rPoint) const;

    void                        CreateSubst();
    void                        DeleteSubst();
    void                        DrawSubst() const;
    void                        ChangeSubstPos(const Point& rVector);
    void                        DrawDragSelectionRect() const;
    void                        ShowEffect(USHORT nPageNo);

                                DECL_LINK( DragSlideHdl, Timer* );
};

} // end of namespace sd

#endif

<|endoftext|>


<commit_before>#include "event.h"
#include "display.h"
#include <stdio.h>

#define internal static
internal ax_event_loop EventLoop = {};

/* NOTE(koekeishiya): Must be thread-safe! Called through AXLibConstructEvent macro */
void AXLibAddEvent(ax_event Event)
{
    if(EventLoop.Running && Event.Handle)
    {
        pthread_mutex_lock(&EventLoop.WorkerLock);
        EventLoop.Queue.push(Event);

        pthread_cond_signal(&EventLoop.State);
        pthread_mutex_unlock(&EventLoop.WorkerLock);
    }
}

/* NOTE(koekeishiya): Uses dynamic dispatch to process events of any type. */
internal void *
AXLibProcessEventQueue(void *)
{
    while(EventLoop.Running)
    {
        pthread_mutex_lock(&EventLoop.StateLock);
        while(!EventLoop.Queue.empty())
        {
            if(!AXLibIsSpaceTransitionInProgress())
            {
                pthread_mutex_lock(&EventLoop.WorkerLock);
                ax_event Event = EventLoop.Queue.front();
                EventLoop.Queue.pop();
                pthread_mutex_unlock(&EventLoop.WorkerLock);

                (*Event.Handle)(&Event);
            }
        }

        while(EventLoop.Queue.empty() && EventLoop.Running)
            pthread_cond_wait(&EventLoop.State, &EventLoop.StateLock);

        pthread_mutex_unlock(&EventLoop.StateLock);
    }

    return NULL;
}

/* NOTE(koekeishiya): Initialize required mutexes and condition for the event-loop */
internal bool
AXLibInitializeEventLoop()
{
   if(pthread_mutex_init(&EventLoop.WorkerLock, NULL) != 0)
   {
       return false;
   }

   if(pthread_mutex_init(&EventLoop.StateLock, NULL) != 0)
   {
       pthread_mutex_destroy(&EventLoop.WorkerLock);
       return false;
   }

   if(pthread_cond_init(&EventLoop.State, NULL) != 0)
   {
        pthread_mutex_destroy(&EventLoop.WorkerLock);
        pthread_mutex_destroy(&EventLoop.StateLock);
        return false;
   }

   return true;
}

/* NOTE(koekeishiya): Destroy mutexes and condition used by the event-loop */
internal void
AXLibTerminateEventLoop()
{
    pthread_cond_destroy(&EventLoop.State);
    pthread_mutex_destroy(&EventLoop.StateLock);
    pthread_mutex_destroy(&EventLoop.WorkerLock);
}

void AXLibPauseEventLoop()
{
    if(EventLoop.Running)
    {
        pthread_mutex_lock(&EventLoop.StateLock);
#ifdef DEBUG_BUILD
        printf("EventLoop: PAUSE\n");
#endif
    }
}

void AXLibResumeEventLoop()
{
    if(EventLoop.Running)
    {
#ifdef DEBUG_BUILD
        printf("EventLoop: RESUME\n");
#endif
        pthread_mutex_unlock(&EventLoop.StateLock);
    }
}

bool AXLibStartEventLoop()
{
    if(!EventLoop.Running && AXLibInitializeEventLoop())
    {
        EventLoop.Running = true;
        pthread_create(&EventLoop.Worker, NULL, &AXLibProcessEventQueue, NULL);
        return true;
    }

    return false;
}

void AXLibStopEventLoop()
{
    if(EventLoop.Running)
    {
        EventLoop.Running = false;
        pthread_cond_signal(&EventLoop.State);
        pthread_join(EventLoop.Worker, NULL);
        AXLibTerminateEventLoop();
    }
}
<commit_msg>ifdef include guard<commit_after>#include "event.h"
#include "display.h"

#ifdef DEBUG_BUILD
#include <stdio.h>
#endif

#define internal static
internal ax_event_loop EventLoop = {};

/* NOTE(koekeishiya): Must be thread-safe! Called through AXLibConstructEvent macro */
void AXLibAddEvent(ax_event Event)
{
    if(EventLoop.Running && Event.Handle)
    {
        pthread_mutex_lock(&EventLoop.WorkerLock);
        EventLoop.Queue.push(Event);

        pthread_cond_signal(&EventLoop.State);
        pthread_mutex_unlock(&EventLoop.WorkerLock);
    }
}

/* NOTE(koekeishiya): Uses dynamic dispatch to process events of any type. */
internal void *
AXLibProcessEventQueue(void *)
{
    while(EventLoop.Running)
    {
        pthread_mutex_lock(&EventLoop.StateLock);
        while(!EventLoop.Queue.empty())
        {
            if(!AXLibIsSpaceTransitionInProgress())
            {
                pthread_mutex_lock(&EventLoop.WorkerLock);
                ax_event Event = EventLoop.Queue.front();
                EventLoop.Queue.pop();
                pthread_mutex_unlock(&EventLoop.WorkerLock);

                (*Event.Handle)(&Event);
            }
        }

        while(EventLoop.Queue.empty() && EventLoop.Running)
            pthread_cond_wait(&EventLoop.State, &EventLoop.StateLock);

        pthread_mutex_unlock(&EventLoop.StateLock);
    }

    return NULL;
}

/* NOTE(koekeishiya): Initialize required mutexes and condition for the event-loop */
internal bool
AXLibInitializeEventLoop()
{
   if(pthread_mutex_init(&EventLoop.WorkerLock, NULL) != 0)
   {
       return false;
   }

   if(pthread_mutex_init(&EventLoop.StateLock, NULL) != 0)
   {
       pthread_mutex_destroy(&EventLoop.WorkerLock);
       return false;
   }

   if(pthread_cond_init(&EventLoop.State, NULL) != 0)
   {
        pthread_mutex_destroy(&EventLoop.WorkerLock);
        pthread_mutex_destroy(&EventLoop.StateLock);
        return false;
   }

   return true;
}

/* NOTE(koekeishiya): Destroy mutexes and condition used by the event-loop */
internal void
AXLibTerminateEventLoop()
{
    pthread_cond_destroy(&EventLoop.State);
    pthread_mutex_destroy(&EventLoop.StateLock);
    pthread_mutex_destroy(&EventLoop.WorkerLock);
}

void AXLibPauseEventLoop()
{
    if(EventLoop.Running)
    {
        pthread_mutex_lock(&EventLoop.StateLock);
#ifdef DEBUG_BUILD
        printf("EventLoop: PAUSE\n");
#endif
    }
}

void AXLibResumeEventLoop()
{
    if(EventLoop.Running)
    {
#ifdef DEBUG_BUILD
        printf("EventLoop: RESUME\n");
#endif
        pthread_mutex_unlock(&EventLoop.StateLock);
    }
}

bool AXLibStartEventLoop()
{
    if(!EventLoop.Running && AXLibInitializeEventLoop())
    {
        EventLoop.Running = true;
        pthread_create(&EventLoop.Worker, NULL, &AXLibProcessEventQueue, NULL);
        return true;
    }

    return false;
}

void AXLibStopEventLoop()
{
    if(EventLoop.Running)
    {
        EventLoop.Running = false;
        pthread_cond_signal(&EventLoop.State);
        pthread_join(EventLoop.Worker, NULL);
        AXLibTerminateEventLoop();
    }
}
<|endoftext|>