def install( julia_download_path='https://julialang-s3.julialang.org/bin/linux/x64/1.4/julia-1.4.0-linux-x86_64.tar.gz', julia_target_path=None): ''' :param julia_download_path: Path for the julia download, you can modify for your preferred version :param julia_target_path: Specify where to install Julia, if not specified will install in $HOME$/julia ''' if julia_target_path == None: julia_target_path = os.path.join(os.path.expanduser("~"), 'julia') if not os.path.isdir(julia_target_path): os.mkdir(julia_target_path) download_path = os.path.join(julia_target_path, 'julia_install.tar.gz') print("Downloading Julia:") wget.download(julia_download_path, download_path) print("\nExtracting...") tar = tarfile.open(download_path, "r:gz") tar.extractall(julia_target_path) _, partial_path = get_julia_path_from_dir(julia_target_path) os.environ["PATH"] += os.pathsep + partial_path os.system("echo '# added by dpmmpython' >> ~/.bashrc") os.system("echo 'export PATH=\"" + partial_path + ":$PATH\"' >> ~/.bashrc") print("Configuring PyJulia") julia.install() julia.Julia(compiled_modules=False) print("Adding DPMMSubClusters package") from julia import Pkg Pkg.add("DPMMSubClusters") print( "Please exit the shell and restart, before attempting to use the package" )
def install_julia_dependencies(): """ Install Julia packages required for quickpomdps """ from julia import Pkg Pkg.add(["PyCall","QuickPOMDPs"])
def setup(compiled_modules=True): julia.install() jl = Julia(compiled_modules=compiled_modules) from julia import Pkg Pkg.add("[email protected]") # Lock to specific version for stability Pkg.add("Distributions") # Install Distributions after Bigsimr
def test_pandamodels_installation(): from julia import Main from julia import Pkg from julia import Base if Base.find_package("PandaModels"): # remove PandaModels to reinstall it Pkg.rm("PandaModels") Pkg.resolve() else: print("PandaModels is not installed yet!") Pkg.Registry.update() Pkg.add("PandaModels") Pkg.build() Pkg.resolve() print("PandaModels is added to julia packages") try: Main.using("PandaModels") print("using PandaModels in its base mode!") except ImportError: raise ImportError("cannot use PandaModels in its base mode")
def Load(file): """Load and environment.""" print("Loading file at: " + file) env = Environment(file) print("Environment loaded!") print(Pkg.installed()) return (env)
def install(julia_project=None): # pragma: no cover import julia julia.install() julia_project = _get_julia_project(julia_project) init_julia() from julia import Pkg Pkg.activate(f"{_escape_filename(julia_project)}") Pkg.update() Pkg.instantiate() Pkg.precompile() warnings.warn( "It is recommended to restart Python after installing PySR's dependencies," " so that the Julia environment is properly initialized.")
try: import julia except ImportError: print("Julia is not installed!") try: from julia import Lathe except: from julia import Pkg Pkg.add("Lathe")
# Something in the below julia interface setup forks a process--setup julia before # importing mpi4py to keep MPI from complaining about the fork from julia.api import Julia jl = Julia(compiled_modules=False) import mpi4py from mpi4py import MPI as pympi import numpy as np comm = pympi.COMM_WORLD # Activate the desired julia environment jl.using('Pkg') from julia import Pkg Pkg.activate(".") jl.using('MPI') jl.using('Random') # for seed! function jl.using('Statistics') # for mean function from julia import Main from julia import MPI as jlmpi # Convert pympi comm to jlmpi comm Main.handle = pympi._handleof(comm) # make handle accessible to julia jl.eval('comm = MPI.Comm(MPI.MPI_Comm(handle))') # create julia comm # WARNING: You might think that we could use a statement like # Main.comm = jlmpi.Comm(jlmpi.MPI_Comm(pympi._handleof(comm))) # to turn the python MPI comm into a julia MPI comm instead of the above `eval`.
def run_jump_model(self, dfm, data, run_uuid, bau=False): profiler = Profiler() time_dict = dict() name = 'reopt' if not bau else 'reopt_bau' reopt_inputs = dfm['reopt_inputs'] if not bau else dfm['reopt_inputs_bau'] self.data = data self.run_uuid = data['outputs']['Scenario']['run_uuid'] self.user_uuid = data['outputs']['Scenario'].get('user_uuid') if platform.system() == "Darwin": ext = ".dylib" elif platform.system() == "Windows": ext = ".dll" else: ext = ".so" # if platform.system() == "Linux": julia_img_file = os.path.join("julia_envs", "Xpress", "JuliaXpressSysimage" + ext) logger.info("Running JuMP model ...") try: if os.path.isfile(julia_img_file): # TODO: clean up this try/except block logger.info("Found Julia image file {}.".format(julia_img_file)) t_start = time.time() api = LibJulia.load() api.sysimage = julia_img_file api.init_julia() from julia import Main time_dict["pyjulia_start_seconds"] = time.time() - t_start else: t_start = time.time() j = julia.Julia() from julia import Main time_dict["pyjulia_start_seconds"] = time.time() - t_start t_start = time.time() Main.using("Pkg") from julia import Pkg time_dict["pyjulia_pkg_seconds"] = time.time() - t_start if os.environ.get("SOLVER") == "xpress": t_start = time.time() Pkg.activate("./julia_envs/Xpress/") time_dict["pyjulia_activate_seconds"] = time.time() - t_start try: t_start = time.time() Main.include("reo/src/reopt_xpress_model.jl") time_dict["pyjulia_include_model_seconds"] = time.time( ) - t_start except ImportError: # should only need to instantiate once Pkg.instantiate() Main.include("reo/src/reopt_xpress_model.jl") t_start = time.time() if bau: model = Main.reopt_model( float(data["inputs"]["Scenario"]["timeout_seconds"]), float(data["inputs"]["Scenario"] ["optimality_tolerance_bau"])) else: model = Main.reopt_model( float(data["inputs"]["Scenario"]["timeout_seconds"]), float(data["inputs"]["Scenario"] ["optimality_tolerance_techs"])) time_dict["pyjulia_make_model_seconds"] = time.time() - t_start elif os.environ.get("SOLVER") == "cbc": t_start = time.time() Pkg.activate("./julia_envs/Cbc/") time_dict["pyjulia_activate_seconds"] = time.time() - t_start t_start = time.time() Main.include("reo/src/reopt_cbc_model.jl") time_dict["pyjulia_include_model_seconds"] = time.time() - t_start t_start = time.time() model = Main.reopt_model( float(data["inputs"]["Scenario"]["timeout_seconds"]), float(data["inputs"]["Scenario"]["optimality_tolerance_bau"])) time_dict["pyjulia_make_model_seconds"] = time.time() - t_start elif os.environ.get("SOLVER") == "scip": t_start = time.time() Pkg.activate("./julia_envs/SCIP/") time_dict["pyjulia_activate_seconds"] = time.time() - t_start t_start = time.time() Main.include("reo/src/reopt_scip_model.jl") time_dict["pyjulia_include_model_seconds"] = time.time() - t_start t_start = time.time() model = Main.reopt_model( float(data["inputs"]["Scenario"]["timeout_seconds"]), float(data["inputs"]["Scenario"]["optimality_tolerance_bau"])) time_dict["pyjulia_make_model_seconds"] = time.time() - t_start else: raise REoptFailedToStartError( message= "The environment variable SOLVER must be set to one of [xpress, cbc, scip].", run_uuid=self.run_uuid, user_uuid=self.user_uuid) if bau or not data["inputs"]["Scenario"]["use_decomposition_model"]: t_start = time.time() Main.include("reo/src/reopt.jl") time_dict["pyjulia_include_reopt_seconds"] = time.time() - t_start t_start = time.time() results = Main.reopt(model, reopt_inputs) time_dict["pyjulia_run_reopt_seconds"] = time.time() - t_start else: t_start = time.time() Main.include("reo/src/reopt_decomposed.jl") time_dict["pyjulia_include_reopt_seconds"] = time.time() - t_start t_start = time.time() results = run_decomposed_model(data, model, reopt_inputs) time_dict["pyjulia_run_reopt_seconds"] = time.time() - t_start results = scrub_numpy_arrays_from_dict(results) results.update(time_dict) except Exception as e: if isinstance(e, REoptFailedToStartError): raise e elif "DimensionMismatch" in e.args[ 0]: # JuMP may mishandle a timeout when no feasible solution is returned msg = "Optimization exceeded timeout: {} seconds.".format( data["inputs"]["Scenario"]["timeout_seconds"]) logger.info(msg) raise OptimizationTimeout(task=name, message=msg, run_uuid=self.run_uuid, user_uuid=self.user_uuid) exc_type, exc_value, exc_traceback = sys.exc_info() print(exc_type) print(exc_value) print(exc_traceback) logger.error("REopt.py raise unexpected error: UUID: " + str(self.run_uuid)) raise UnexpectedError(exc_type, exc_value, traceback.format_tb(exc_traceback), task=name, run_uuid=self.run_uuid, user_uuid=self.user_uuid) else: status = results["status"] logger.info("REopt run successful. Status {}".format(status)) if bau: dfm['results_bau'] = results # will be flat dict else: dfm['results'] = results if status.strip().lower() == 'timed-out': msg = "Optimization exceeded timeout: {} seconds.".format( data["inputs"]["Scenario"]["timeout_seconds"]) logger.info(msg) raise OptimizationTimeout(task=name, message=msg, run_uuid=self.run_uuid, user_uuid=self.user_uuid) elif status.strip().lower() != 'optimal': logger.error( "REopt status not optimal. Raising NotOptimal Exception.") raise NotOptimal(task=name, run_uuid=self.run_uuid, status=status.strip(), user_uuid=self.user_uuid) profiler.profileEnd() ModelManager.updateModel('ProfileModel', {name + '_seconds': profiler.getDuration()}, run_uuid) # reduce the amount data being transferred between tasks if bau: del dfm['reopt_inputs_bau'] else: del dfm['reopt_inputs'] return dfm
__maintainer__ = 'Glaucon Garcia' __email__ = '*****@*****.**' __status__ = 'Development' if __name__ == '__main__': setup(name=__title__, version=__version__, url=__url__, description=__description__, long_description=__description__, author=__author__, author_email=__email__, license=__license__, keywords=__keywords__, packages=find_packages(), include_package_data=True, install_requires=[ 'julia', ], classifiers=[ 'Development Status :: 1 - Development', 'Intended Audience :: Developers', 'Intended Audience :: Science/Research', 'Operating System :: OS Independent', 'Programming Language :: Python :: 3', 'Topic :: Utilities' ]) julia.install() Pkg.add("JSON") Pkg.add("JuMP")
def test_pandamodels_dev_mode(): from julia import Main from julia import Pkg from julia import Base if Base.find_package("PandaModels"): # remove PandaModels to reinstall it Pkg.rm("PandaModels") Pkg.resolve() Pkg.Registry.update() Pkg.add("PandaModels") print("installing dev mode is a slow process!") Pkg.resolve() Pkg.develop("PandaModels") # add pandamodels dependencies: slow process Pkg.instantiate() Pkg.build() Pkg.resolve() print("dev mode of PandaModels is added to julia packages") try: Pkg.activate("PandaModels") Main.using("PandaModels") print("using PandaModels in its dev mode!") except ImportError: # assert False raise ImportError("cannot use PandaModels in its dev mode") # activate julia base mode Pkg.activate() Pkg.free("PandaModels") Pkg.resolve()
def _call_pandamodels(buffer_file, julia_file, dev_mode): # pragma: no cover try: import julia from julia import Main from julia import Pkg from julia import Base except ImportError: raise ImportError( "Please install pyjulia properly to run pandapower with PandaModels.jl." ) try: julia.Julia() except: raise UserWarning( "Could not connect to julia, please check that Julia is installed and pyjulia is correctly configured" ) if not Base.find_package("PandaModels"): logger.info( "PandaModels.jl is not installed in julia. It is added now!") Pkg.Registry.update() Pkg.add("PandaModels") if dev_mode: logger.info("installing dev mode is a slow process!") Pkg.resolve() Pkg.develop("PandaModels") # add pandamodels dependencies: slow process Pkg.instantiate() Pkg.build() Pkg.resolve() logger.info("Successfully added PandaModels") if dev_mode: Pkg.develop("PandaModels") Pkg.build() Pkg.resolve() Pkg.activate("PandaModels") try: Main.using("PandaModels") except ImportError: raise ImportError("cannot use PandaModels") Main.buffer_file = buffer_file result_pm = Main.eval(julia_file + "(buffer_file)") # if dev_mode: # Pkg.activate() # Pkg.free("PandaModels") # Pkg.resolve() return result_pm
# The Light-Dark problem from https://arxiv.org/pdf/1709.06196.pdf from quickpomdps import QuickPOMDP from julia import Pkg Pkg.add(["POMDPs", "POMDPSimulators", "POMDPPolicies", "POMDPModelTools", "Distributions", "QMDP"]) from julia.Main import Float64 from julia.POMDPs import solve, pdf from julia.QMDP import QMDPSolver from julia.POMDPSimulators import stepthrough from julia.POMDPPolicies import alphavectors from julia.POMDPModelTools import Uniform, Deterministic from julia.Distributions import Normal r = 60 light_loc = 10 def transition(s, a): if a == 0: return Deterministic(r+1) else: return Deterministic(min(max(s+a, -r), r)) def observation(s, a, sp): return Normal(sp, abs(sp - light_loc) + 0.0001) def reward(s, a, sp): if a == 0: return 100.0 if s == 0 else -100.0 else: return -1.0
def List(self): """Lists the current packages inside of this environment""" return (Pkg.installed())
def pysr( X, y, weights=None, binary_operators=None, unary_operators=None, procs=cpu_count(), loss="L2DistLoss()", populations=20, niterations=100, ncyclesperiteration=300, alpha=0.1, annealing=False, fractionReplaced=0.10, fractionReplacedHof=0.10, npop=1000, parsimony=1e-4, migration=True, hofMigration=True, shouldOptimizeConstants=True, topn=10, weightAddNode=1, weightInsertNode=3, weightDeleteNode=3, weightDoNothing=1, weightMutateConstant=10, weightMutateOperator=1, weightRandomize=1, weightSimplify=0.002, perturbationFactor=1.0, extra_sympy_mappings=None, extra_torch_mappings=None, extra_jax_mappings=None, equation_file=None, verbosity=1e9, progress=None, maxsize=20, fast_cycle=False, maxdepth=None, variable_names=None, batching=False, batchSize=50, select_k_features=None, warmupMaxsizeBy=0.0, constraints=None, useFrequency=True, tempdir=None, delete_tempfiles=True, julia_project=None, update=True, temp_equation_file=False, output_jax_format=False, output_torch_format=False, optimizer_algorithm="BFGS", optimizer_nrestarts=3, optimize_probability=1.0, optimizer_iterations=10, tournament_selection_n=10, tournament_selection_p=1.0, denoise=False, Xresampled=None, precision=32, multithreading=None, **kwargs, ): """Run symbolic regression to fit f(X[i, :]) ~ y[i] for all i. Note: most default parameters have been tuned over several example equations, but you should adjust `niterations`, `binary_operators`, `unary_operators` to your requirements. You can view more detailed explanations of the options on the [options page](https://pysr.readthedocs.io/en/latest/docs/options/) of the documentation. :param X: 2D array. Rows are examples, columns are features. If pandas DataFrame, the columns are used for variable names (so make sure they don't contain spaces). :type X: np.ndarray/pandas.DataFrame :param y: 1D array (rows are examples) or 2D array (rows are examples, columns are outputs). Putting in a 2D array will trigger a search for equations for each feature of y. :type y: np.ndarray :param weights: same shape as y. Each element is how to weight the mean-square-error loss for that particular element of y. :type weights: np.ndarray :param binary_operators: List of strings giving the binary operators in Julia's Base. Default is ["+", "-", "*", "/",]. :type binary_operators: list :param unary_operators: Same but for operators taking a single scalar. Default is []. :type unary_operators: list :param procs: Number of processes (=number of populations running). :type procs: int :param loss: String of Julia code specifying the loss function. Can either be a loss from LossFunctions.jl, or your own loss written as a function. Examples of custom written losses include: `myloss(x, y) = abs(x-y)` for non-weighted, or `myloss(x, y, w) = w*abs(x-y)` for weighted. Among the included losses, these are as follows. Regression: `LPDistLoss{P}()`, `L1DistLoss()`, `L2DistLoss()` (mean square), `LogitDistLoss()`, `HuberLoss(d)`, `L1EpsilonInsLoss(ϵ)`, `L2EpsilonInsLoss(ϵ)`, `PeriodicLoss(c)`, `QuantileLoss(τ)`. Classification: `ZeroOneLoss()`, `PerceptronLoss()`, `L1HingeLoss()`, `SmoothedL1HingeLoss(γ)`, `ModifiedHuberLoss()`, `L2MarginLoss()`, `ExpLoss()`, `SigmoidLoss()`, `DWDMarginLoss(q)`. :type loss: str :param populations: Number of populations running. :type populations: int :param niterations: Number of iterations of the algorithm to run. The best equations are printed, and migrate between populations, at the end of each. :type niterations: int :param ncyclesperiteration: Number of total mutations to run, per 10 samples of the population, per iteration. :type ncyclesperiteration: int :param alpha: Initial temperature. :type alpha: float :param annealing: Whether to use annealing. You should (and it is default). :type annealing: bool :param fractionReplaced: How much of population to replace with migrating equations from other populations. :type fractionReplaced: float :param fractionReplacedHof: How much of population to replace with migrating equations from hall of fame. :type fractionReplacedHof: float :param npop: Number of individuals in each population :type npop: int :param parsimony: Multiplicative factor for how much to punish complexity. :type parsimony: float :param migration: Whether to migrate. :type migration: bool :param hofMigration: Whether to have the hall of fame migrate. :type hofMigration: bool :param shouldOptimizeConstants: Whether to numerically optimize constants (Nelder-Mead/Newton) at the end of each iteration. :type shouldOptimizeConstants: bool :param topn: How many top individuals migrate from each population. :type topn: int :param perturbationFactor: Constants are perturbed by a max factor of (perturbationFactor*T + 1). Either multiplied by this or divided by this. :type perturbationFactor: float :param weightAddNode: Relative likelihood for mutation to add a node :type weightAddNode: float :param weightInsertNode: Relative likelihood for mutation to insert a node :type weightInsertNode: float :param weightDeleteNode: Relative likelihood for mutation to delete a node :type weightDeleteNode: float :param weightDoNothing: Relative likelihood for mutation to leave the individual :type weightDoNothing: float :param weightMutateConstant: Relative likelihood for mutation to change the constant slightly in a random direction. :type weightMutateConstant: float :param weightMutateOperator: Relative likelihood for mutation to swap an operator. :type weightMutateOperator: float :param weightRandomize: Relative likelihood for mutation to completely delete and then randomly generate the equation :type weightRandomize: float :param weightSimplify: Relative likelihood for mutation to simplify constant parts by evaluation :type weightSimplify: float :param equation_file: Where to save the files (.csv separated by |) :type equation_file: str :param verbosity: What verbosity level to use. 0 means minimal print statements. :type verbosity: int :param progress: Whether to use a progress bar instead of printing to stdout. :type progress: bool :param maxsize: Max size of an equation. :type maxsize: int :param maxdepth: Max depth of an equation. You can use both maxsize and maxdepth. maxdepth is by default set to = maxsize, which means that it is redundant. :type maxdepth: int :param fast_cycle: (experimental) - batch over population subsamples. This is a slightly different algorithm than regularized evolution, but does cycles 15% faster. May be algorithmically less efficient. :type fast_cycle: bool :param variable_names: a list of names for the variables, other than "x0", "x1", etc. :type variable_names: list :param batching: whether to compare population members on small batches during evolution. Still uses full dataset for comparing against hall of fame. :type batching: bool :param batchSize: the amount of data to use if doing batching. :type batchSize: int :param select_k_features: whether to run feature selection in Python using random forests, before passing to the symbolic regression code. None means no feature selection; an int means select that many features. :type select_k_features: None/int :param warmupMaxsizeBy: whether to slowly increase max size from a small number up to the maxsize (if greater than 0). If greater than 0, says the fraction of training time at which the current maxsize will reach the user-passed maxsize. :type warmupMaxsizeBy: float :param constraints: dictionary of int (unary) or 2-tuples (binary), this enforces maxsize constraints on the individual arguments of operators. E.g., `'pow': (-1, 1)` says that power laws can have any complexity left argument, but only 1 complexity exponent. Use this to force more interpretable solutions. :type constraints: dict :param useFrequency: whether to measure the frequency of complexities, and use that instead of parsimony to explore equation space. Will naturally find equations of all complexities. :type useFrequency: bool :param tempdir: directory for the temporary files :type tempdir: str/None :param delete_tempfiles: whether to delete the temporary files after finishing :type delete_tempfiles: bool :param julia_project: a Julia environment location containing a Project.toml (and potentially the source code for SymbolicRegression.jl). Default gives the Python package directory, where a Project.toml file should be present from the install. :type julia_project: str/None :param update: Whether to automatically update Julia packages. :type update: bool :param temp_equation_file: Whether to put the hall of fame file in the temp directory. Deletion is then controlled with the delete_tempfiles argument. :type temp_equation_file: bool :param output_jax_format: Whether to create a 'jax_format' column in the output, containing jax-callable functions and the default parameters in a jax array. :type output_jax_format: bool :param output_torch_format: Whether to create a 'torch_format' column in the output, containing a torch module with trainable parameters. :type output_torch_format: bool :param tournament_selection_n: Number of expressions to consider in each tournament. :type tournament_selection_n: int :param tournament_selection_p: Probability of selecting the best expression in each tournament. The probability will decay as p*(1-p)^n for other expressions, sorted by loss. :type tournament_selection_p: float :param denoise: Whether to use a Gaussian Process to denoise the data before inputting to PySR. Can help PySR fit noisy data. :type denoise: bool :param precision: What precision to use for the data. By default this is 32 (float32), but you can select 64 or 16 as well. :type precision: int :param multithreading: Use multithreading instead of distributed backend. Default is yes. Using procs=0 will turn off both. :type multithreading: bool :param **kwargs: Other options passed to SymbolicRegression.Options, for example, if you modify SymbolicRegression.jl to include additional arguments. :type **kwargs: dict :returns: Results dataframe, giving complexity, MSE, and equations (as strings), as well as functional forms. If list, each element corresponds to a dataframe of equations for each output. :type: pd.DataFrame/list """ global already_ran if binary_operators is None: binary_operators = "+ * - /".split(" ") if unary_operators is None: unary_operators = [] if extra_sympy_mappings is None: extra_sympy_mappings = {} if variable_names is None: variable_names = [] if constraints is None: constraints = {} if multithreading is None: # Default is multithreading=True, unless explicitly set, # or procs is set to 0 (serial mode). multithreading = procs != 0 global Main if Main is None: if multithreading: os.environ["JULIA_NUM_THREADS"] = str(procs) Main = init_julia() buffer_available = "buffer" in sys.stdout.__dir__() if progress is not None: if progress and not buffer_available: warnings.warn( "Note: it looks like you are running in Jupyter. The progress bar will be turned off." ) progress = False else: progress = buffer_available assert optimizer_algorithm in ["NelderMead", "BFGS"] assert tournament_selection_n < npop if isinstance(X, pd.DataFrame): variable_names = list(X.columns) X = np.array(X) if len(X.shape) == 1: X = X[:, None] assert not isinstance(y, pd.DataFrame) if len(variable_names) == 0: variable_names = [f"x{i}" for i in range(X.shape[1])] if extra_jax_mappings is not None: for value in extra_jax_mappings.values(): if not isinstance(value, str): raise NotImplementedError( "extra_jax_mappings must have keys that are strings! e.g., {sympy.sqrt: 'jnp.sqrt'}." ) if extra_torch_mappings is not None: for value in extra_jax_mappings.values(): if not callable(value): raise NotImplementedError( "extra_torch_mappings must be callable functions! e.g., {sympy.sqrt: torch.sqrt}." ) use_custom_variable_names = len(variable_names) != 0 # TODO: this is always true. _check_assertions( X, binary_operators, unary_operators, use_custom_variable_names, variable_names, weights, y, ) if len(X) > 10000 and not batching: warnings.warn( "Note: you are running with more than 10,000 datapoints. You should consider turning on batching (https://pysr.readthedocs.io/en/latest/docs/options/#batching). You should also reconsider if you need that many datapoints. Unless you have a large amount of noise (in which case you should smooth your dataset first), generally < 10,000 datapoints is enough to find a functional form with symbolic regression. More datapoints will lower the search speed." ) if maxsize > 40: warnings.warn( "Note: Using a large maxsize for the equation search will be exponentially slower and use significant memory. You should consider turning `useFrequency` to False, and perhaps use `warmupMaxsizeBy`." ) if maxsize < 7: raise NotImplementedError("PySR requires a maxsize of at least 7") X, selection = _handle_feature_selection(X, select_k_features, y, variable_names) if maxdepth is None: maxdepth = maxsize if isinstance(binary_operators, str): binary_operators = [binary_operators] if isinstance(unary_operators, str): unary_operators = [unary_operators] if len(y.shape) == 1 or (len(y.shape) == 2 and y.shape[1] == 1): multioutput = False nout = 1 y = y.reshape(-1) elif len(y.shape) == 2: multioutput = True nout = y.shape[1] else: raise NotImplementedError("y shape not supported!") if denoise: if weights is not None: raise NotImplementedError( "No weights for denoising - the weights are learned.") if Xresampled is not None: # Select among only the selected features: if isinstance(Xresampled, pd.DataFrame): # Handle Xresampled is pandas dataframe if selection is not None: Xresampled = Xresampled[[ variable_names[i] for i in selection ]] else: Xresampled = Xresampled[variable_names] Xresampled = np.array(Xresampled) else: if selection is not None: Xresampled = Xresampled[:, selection] if multioutput: y = np.stack( [ _denoise(X, y[:, i], Xresampled=Xresampled)[1] for i in range(nout) ], axis=1, ) if Xresampled is not None: X = Xresampled else: X, y = _denoise(X, y, Xresampled=Xresampled) julia_project = _get_julia_project(julia_project) tmpdir = Path(tempfile.mkdtemp(dir=tempdir)) if temp_equation_file: equation_file = tmpdir / "hall_of_fame.csv" elif equation_file is None: date_time = datetime.now().strftime("%Y-%m-%d_%H%M%S.%f")[:-3] equation_file = "hall_of_fame_" + date_time + ".csv" _create_inline_operators(binary_operators=binary_operators, unary_operators=unary_operators) _handle_constraints( binary_operators=binary_operators, unary_operators=unary_operators, constraints=constraints, ) una_constraints = [constraints[op] for op in unary_operators] bin_constraints = [constraints[op] for op in binary_operators] try: # TODO: is this needed since Julia now prints directly to stdout? term_width = shutil.get_terminal_size().columns except: _, term_width = subprocess.check_output(["stty", "size"]).split() if not already_ran: from julia import Pkg Pkg.activate(f"{_escape_filename(julia_project)}") try: if update: Pkg.resolve() Pkg.instantiate() else: Pkg.instantiate() except RuntimeError as e: raise ImportError(f""" Required dependencies are not installed or built. Run the following code in the Python REPL: >>> import pysr >>> pysr.install() Tried to activate project {julia_project} but failed.""") from e Main.eval("using SymbolicRegression") Main.plus = Main.eval("(+)") Main.sub = Main.eval("(-)") Main.mult = Main.eval("(*)") Main.pow = Main.eval("(^)") Main.div = Main.eval("(/)") Main.custom_loss = Main.eval(loss) mutationWeights = [ float(weightMutateConstant), float(weightMutateOperator), float(weightAddNode), float(weightInsertNode), float(weightDeleteNode), float(weightSimplify), float(weightRandomize), float(weightDoNothing), ] options = Main.Options( binary_operators=Main.eval( str(tuple(binary_operators)).replace("'", "")), unary_operators=Main.eval( str(tuple(unary_operators)).replace("'", "")), bin_constraints=bin_constraints, una_constraints=una_constraints, parsimony=float(parsimony), loss=Main.custom_loss, alpha=float(alpha), maxsize=int(maxsize), maxdepth=int(maxdepth), fast_cycle=fast_cycle, migration=migration, hofMigration=hofMigration, fractionReplacedHof=float(fractionReplacedHof), shouldOptimizeConstants=shouldOptimizeConstants, hofFile=_escape_filename(equation_file), npopulations=int(populations), optimizer_algorithm=optimizer_algorithm, optimizer_nrestarts=int(optimizer_nrestarts), optimize_probability=float(optimize_probability), optimizer_iterations=int(optimizer_iterations), perturbationFactor=float(perturbationFactor), annealing=annealing, batching=batching, batchSize=int(min([batchSize, len(X)]) if batching else len(X)), mutationWeights=mutationWeights, warmupMaxsizeBy=float(warmupMaxsizeBy), useFrequency=useFrequency, npop=int(npop), ns=int(tournament_selection_n), probPickFirst=float(tournament_selection_p), ncyclesperiteration=int(ncyclesperiteration), fractionReplaced=float(fractionReplaced), topn=int(topn), verbosity=int(verbosity), progress=progress, terminal_width=int(term_width), **kwargs, ) np_dtype = {16: np.float16, 32: np.float32, 64: np.float64}[precision] Main.X = np.array(X, dtype=np_dtype).T if len(y.shape) == 1: Main.y = np.array(y, dtype=np_dtype) else: Main.y = np.array(y, dtype=np_dtype).T if weights is not None: if len(weights.shape) == 1: Main.weights = np.array(weights, dtype=np_dtype) else: Main.weights = np.array(weights, dtype=np_dtype).T else: Main.weights = None cprocs = 0 if multithreading else procs raw_julia_output = Main.EquationSearch( Main.X, Main.y, weights=Main.weights, niterations=int(niterations), varMap=(variable_names if selection is None else [variable_names[i] for i in selection]), options=options, numprocs=int(cprocs), multithreading=bool(multithreading), ) _set_globals( X=X, equation_file=equation_file, variable_names=variable_names, extra_sympy_mappings=extra_sympy_mappings, extra_torch_mappings=extra_torch_mappings, extra_jax_mappings=extra_jax_mappings, output_jax_format=output_jax_format, output_torch_format=output_torch_format, multioutput=multioutput, nout=nout, selection=selection, raw_julia_output=raw_julia_output, ) equations = get_hof( equation_file=equation_file, n_features=X.shape[1], variable_names=variable_names, output_jax_format=output_jax_format, output_torch_format=output_torch_format, selection=selection, extra_sympy_mappings=extra_sympy_mappings, extra_jax_mappings=extra_jax_mappings, extra_torch_mappings=extra_torch_mappings, multioutput=multioutput, nout=nout, ) if delete_tempfiles: shutil.rmtree(tmpdir) already_ran = True return equations
import julia julia.install() from julia import Pkg Pkg.add('QXZoo') import pyqx.qxzoo
# Configure PyJulia import julia julia.install() # install PyCall.jl etc. # Add the Tempotrons.jl package from julia import Pkg Pkg.add(url = "https://github.com/bci4cpl/Tempotrons.jl")