Example #1
0
    def _compute_eps(lam):
        session = WolframLanguageSession(wlpath)
        session.evaluate(
            wlexpr('''
           randomgamma[alpha_, beta_, gamma_, samples_] := RandomVariate[GammaDistribution[alpha, beta, gamma, 0], samples];
         '''))
        random_gamma = session.function(wlexpr('randomgamma'))

        session.evaluate(
            wlexpr('''
           integrant[exponents_, beta_, dimension_, clippingbound_, lam_, r_, q_] := Mean[NIntegrate[
                           (Sin[x]^(dimension-2)*Gamma[dimension/2]/(Sqrt[Pi]*Gamma[(dimension-1)/2]))*(((1-q)*(1-q+
                           q*Exp[(r^exponents-(r^2+clippingbound^2-2*r*clippingbound*Cos[x])^(exponents/2))/beta])^(lam))
                        +(q*(1-q+q*Exp[((r^2+clippingbound^2+2*r*clippingbound*Cos[x])^(exponents/2)-r^exponents)/beta])^(lam))),{x,0,Pi}
                           ]];
         '''))
        integrant_moment = session.function(wlexpr('integrant'))
        samples = random_gamma(FLAGS.dimension / FLAGS.exponents,
                               beta**(1 / FLAGS.exponents), FLAGS.exponents,
                               FLAGS.num_samples)
        moment = integrant_moment(FLAGS.exponents, beta, FLAGS.dimension,
                                  FLAGS.clippingbound, lam, samples, FLAGS.q)
        eps = (FLAGS.T * mp.log(moment) + mp.log(1 / FLAGS.delta)) / lam
        session.terminate()
        return eps
Example #2
0
def compute_dp(lam):
    session = WolframLanguageSession(wlpath)
    session.evaluate(
        wlexpr('''
       randomgamma[alpha_, beta_, gamma_, samples_] := RandomVariate[GammaDistribution[alpha, beta, gamma, 0], samples];
     '''))
    random_gamma = session.function(wlexpr('randomgamma'))

    session.evaluate(
        wlexpr('''
       integrant[p_, beta_, d_, Delta_, lam_, r_] := Mean[NIntegrate[
       Sin[x]^(d-2)*Gamma[d/2]/(Sqrt[Pi]*Gamma[(d-1)/2])*(0.99+0.01*Exp[(r^p-(r^2+Delta^2+2*r*Delta*Cos[x])^(p/2))/beta])^(-lam),{x,0,Pi}
       ]];
     '''))
    integrant_moment = session.function(wlexpr('integrant'))
    samples = random_gamma(d / p, beta**(1 / p), p, num_samples)
    # print(samples)
    moment = integrant_moment(p, beta, d, Delta, lam, samples)
    # print(moment)
    eps = (T * mp.log(moment) + mp.log(1 / delta)) / lam
    session.terminate()
    return eps
Example #3
0
class Engine:
    def __init__(self):
        config = get_config()
        wolfram_path = config.get("DEFAULT", "WOLFRAM_PATH")
        self.image_path = os.path.join(os.getcwd(), 'static', 'city')
        atexit.register(self.cleanup)
        if wolfram_path is None or len(wolfram_path) == 0:
            self.session = WolframLanguageSession()
            print("Wolfram Engine session opened on default path.")
        else:
            self.session = WolframLanguageSession(wolfram_path)
            print(f"Wolfram Engine session opened on '{wolfram_path}'.")
        self._define_wolfram_functions()

    def _define_wolfram_functions(self):
        self.get_weather = self.session.function(wlexpr('<|"Temperature" -> WeatherData[#, "Temperature"], "WindSpeed" ->WeatherData[#,  "WindSpeed"],"Pressure"-> WeatherData[#,"Pressure"]|>&'))
        self.get_city = self.session.function(wlexpr('Module[{cities}, cities = TextCases[#, "City"];If[Length[cities] > 0, First[cities], ""]]&'))

    def test(self):
        self.check_session()
        return self.session.evaluate(wlexpr('NIntegrate[Sin[Sin[x]], {x, 0, 2}]'))

    def get_city_image(self, name):
        # search existing images if present
        lname = str.lower(name)
        for file in os.listdir(self.image_path):
            if file.endswith(".png"):
                if file == f"{lname}.png":
                    print(f"Found image for '{name}' in cache.")
                    return
        # get the image via websearch
        graphic = self.session.evaluate(wlexpr(f'WebImageSearch["{name}", "Images", MaxItems -> 1][[1]]'))

        path = os.path.join(self.image_path, f"{lname}.png")
        png_export = wl.Export(path, graphic, "PNG")
        return self.session.evaluate(png_export)

    def get_weather_info(self, text) -> dict:
        """
            Returns a dictionary with some weather info for the first city found in the given
            (natural language) text.
        :param text: any text
        """
        self.check_session()
        if text is None or len(text) == 0:
            return {}
        city = self.get_city(text)
        if city is None or len(city) == 0:
            return {}
        print(f"Found city: {city}")
        found = self.get_weather(city)

        if isinstance(found, dict) and found["Temperature"].args[0] != "NotAvailable":
            self.get_city_image(city)

            return {
                "Input": text,
                "City": city,
                "Temperature": found["Temperature"].args[0],
                "WindSpeed": found["WindSpeed"].args[0],
                "Pressure": found["Pressure"].args[0],
                "Info": self.session.evaluate(wlexpr(f'TextSentences[WikipediaData["{city}"]][[;; 5]]'))[0]
            }
        else:
            return {}

    def check_session(self):
        if self.session is None:
            raise Exception("The Engine is not present.")

    # noinspection PyBroadException
    def cleanup(self):
        """
            Note that there is no way to catch the SIGKILL
            and stop the engine gracefully if this happens.
        :return:
        """
        try:
            if self.session is not None:
                self.session.stop()
                print("Wolfram Engine stopped.")
        except Exception:
            pass
class WolframSampler:
    def __init__(self):
        """A wrapper to generateExperiments.wls

        Written as a class so the Wolfram session is only once at __init__ time.
        """
        self.session = WolframLanguageSession(kernel=wolfram_kernel_path)
        self.session.evaluate('<<./capture/generate/randomSampling.wls')
        self.session.evaluate('<<./capture/generate/enumerativeSampling.wls')
        self._randomlySample = self.session.function('generateExperiments')
        self._enumerativelySample = self.session.function(
            'generateEnumerations')

    def randomlySample(self,
                       reagentVectors,
                       oldReagents=None,
                       nExpt=96,
                       maxMolarity=9.,
                       finalVolume=500.):
        """Randomly sample possible experiments in the convex hull of concentration space defined by the reagentVectors

        Runs Josh's Mathematica function called `generateExperiments` defined in `randomSampling.wls`
        Shadows default arguments set at Wolfram level.
        Currently does not expose processVaules argument.

        :param reagentVectors: a dictionary of vector representations of reagents living in species-concentration space
        :param nExpt: the number of samples to draw
        :param maxMolarity: the maximum concentration of any species: defines a hypercube bounding the convex hull
        :param finalVolume: a scalar to act on the concentrations to convert to desired volume
        :return: a dictionary mapping: {reagents => list(volumes)} where list(volumes) has length nExpt
        :raises TypeError: since Mathematica will fail silently on incorrect types
        """
        ## Easy mathematica debugging (get an error, uncomment here for vectors)
        #print("new", reagentVectors, '\n')
        #print('to be removed', oldReagents, '\n')
        if not isinstance(reagentVectors, dict):
            raise TypeError('reagentVectors must be dict, got {}'.format(
                type(reagentVectors)))
        if not isinstance(nExpt, int):
            raise TypeError('nExpt must be int, got {}'.format(type(nExpt)))
        if not isinstance(maxMolarity, float):
            raise TypeError('maxMolarity must be float, got {}'.format(
                type(maxMolarity)))
        if not isinstance(finalVolume, float):
            raise TypeError('finalVolume must be float, got {}'.format(
                type(finalVolume)))
        if oldReagents:
            if not isinstance(oldReagents, dict):
                raise TypeError('oldReagents must be dict, got {}'.format(
                    type(oldReagents)))
        if oldReagents:
            result = self._randomlySample(reagentVectors, oldReagents, nExpt,
                                          maxMolarity, finalVolume)
            #            result = self._randomlySample(oldReagents, reagentVectors, nExpt, maxMolarity, finalVolume)
            if "Volume of remaining space is zero" in result:
                raise ValueError(
                    'New reagents define a convex hull that is covered by that of old reagents.'
                )
        else:
            result = self._randomlySample(reagentVectors, nExpt, maxMolarity,
                                          finalVolume)

        return result

    def enumerativelySample(self,
                            reagentVectors,
                            uniqueChemNames,
                            deltaV=10.,
                            maxMolarity=9.,
                            finalVolume=500.):
        """Enumeratively sample possible experiments in the convex hull of concentration space defined by the reagentVectors

        Runs Josh's Mathematica function called `achievableGrid` defined in `enumerativeSampling.wls`
        Shadows default arguments set at Wolfram level.

        :param reagentVectors: a dictionary of vector representations of reagents living in species-concentration space
        :param uniqueChemNames: list of chemicals making up the reagents
        :param maxMolarity: the maximum concentration of any species: defines a hypercube bounding the convex hull
        :param deltaV: the spacing of reagent volumes that define the spacing of the grid in concentration space
        :param finalVolume: a scalar to act on the concentration points to convert to desired volume
        :return:  a dictionary mapping: {reagents => list(volumes)}
        :raises TypeError: since Mathematica will fail silently on incorrect types
        """

        if not isinstance(reagentVectors, dict):
            raise TypeError('reagentVectors must be dict, got {}'.format(
                type(reagentVectors)))
        if not isinstance(uniqueChemNames, list):
            raise TypeError('uniqueChemNames must be a list, got {}'.format(
                type(uniqueChemNames)))
        if not isinstance(maxMolarity, float):
            raise TypeError('maxMolarity must be float, got {}'.format(
                type(maxMolarity)))
        if not isinstance(deltaV, float):
            raise TypeError('deltaV must be float, got {}'.format(
                type(deltaV)))
        if not isinstance(finalVolume, float):
            raise TypeError('finalVolume must be float, got {}'.format(
                type(finalVolume)))

        return self._enumerativelySample(reagentVectors, uniqueChemNames,
                                         deltaV, maxMolarity, finalVolume)

    def terminate(self):
        """Kill the session thread"""
        self.session.terminate()