<commit_before>import { Observable, Observer, Subject, Subscription } from "rxjs";

import {
    cloneEvaluation,
    cloneOrganism,
    Environment,
    FitnessObjective,
    Gene,
    Genome,
    IEvaluation,
    IGenomeOptions,
    IOrganismOptions,
    IPopulationOptions,
    Organism,
    ReactiveCollection,
    ReactiveProperty,
    reproduceManyToOne,
    value,
} from "../index";

import * as Chance from "chance";
import * as _ from "lodash";
const chance = new Chance();

export abstract class Population<
    Gen extends IGenomeOptions,
    Pop extends IPopulationOptions,
    Org extends IOrganismOptions,
    Data, Pheno, AState, EState> {

    public avgFitness: ReactiveProperty<number> = new ReactiveProperty<number>();

    public evaluations: Subject<IEvaluation<Gen, Data, Pheno>> =
    new Subject<IEvaluation<Gen, Data, Pheno>>();

    private subs: Subscription = new Subscription();

    private generation: number = 0;

    constructor(
        public genOptions: Gen,
        public popOptions: Pop,
        public orgOptions: Org) {
    }

    // mutate the organism based on evaluation
    public abstract mutate(
        evaluation: IEvaluation<Gen, Data, Pheno>): Genome<Gen>;

    // create an organism to inject into environment.
    public abstract createOrganism(
        genome: Genome<Gen>,
        options: IOrganismOptions,
    ): Organism<Gen, Pop, Org, Data, Pheno, AState, EState>;

    public createOrganisms(n: number): Array<Organism<Gen, Pop, Org, Data, Pheno, AState, EState>> {
        return _.range(n)
            .map((i) => this.createOrganism(new Genome(this.genOptions), this.orgOptions));
    }

    // spawns and evenly distributes organisms across all envs
    public populate(
        organisms: Observer<Organism<Gen, Pop, Org, Data, Pheno, AState, EState>>,
        top: ReactiveCollection<IEvaluation<Gen, Data, Pheno>>,
    ): Subscription {
        const orgs = this.createOrganisms(this.popOptions.size);

        for (const o of orgs) {
            organisms.next(o);
        }

        return this
            .updateGenotype(this.evaluations, top)
            .map((genome) => this.createOrganism(genome, this.orgOptions))
            .subscribe(
                (o) => organisms.next(o),
                (error) => console.log(`${error}`),
            );
    }

    // update genotypes as they are evaluated
    private updateGenotype(
        evaluations: Observable<IEvaluation<Gen, Data, Pheno>>,
        top: ReactiveCollection<IEvaluation<Gen, Data, Pheno>>): Observable<Genome<Gen>> {

        return evaluations
            .map((e) => {
                const update = chance.weighted(
                    [
                        this.mutateGenotype,
                        this.reproduceGenotype,
                        this.randomizeGenotype,
                    ],
                    [
                        this.popOptions.weights.mutate,
                        this.popOptions.weights.reproduce,
                        this.popOptions.weights.randomize,
                    ],
                );

                return update(e, top);
            });
    }
<commit_msg>added caller to error message<commit_after>import { Observable, Observer, Subject, Subscription } from "rxjs";

import {
    cloneEvaluation,
    cloneOrganism,
    Environment,
    FitnessObjective,
    Gene,
    Genome,
    IEvaluation,
    IGenomeOptions,
    IOrganismOptions,
    IPopulationOptions,
    Organism,
    ReactiveCollection,
    ReactiveProperty,
    reproduceManyToOne,
    value,
} from "../index";

import * as Chance from "chance";
import * as _ from "lodash";
const chance = new Chance();

export abstract class Population<
    Gen extends IGenomeOptions,
    Pop extends IPopulationOptions,
    Org extends IOrganismOptions,
    Data, Pheno, AState, EState> {

    public avgFitness: ReactiveProperty<number> = new ReactiveProperty<number>();

    public evaluations: Subject<IEvaluation<Gen, Data, Pheno>> =
    new Subject<IEvaluation<Gen, Data, Pheno>>();

    private subs: Subscription = new Subscription();

    private generation: number = 0;

    constructor(
        public genOptions: Gen,
        public popOptions: Pop,
        public orgOptions: Org) {
    }

    // mutate the organism based on evaluation
    public abstract mutate(
        evaluation: IEvaluation<Gen, Data, Pheno>): Genome<Gen>;

    // create an organism to inject into environment.
    public abstract createOrganism(
        genome: Genome<Gen>,
        options: IOrganismOptions,
    ): Organism<Gen, Pop, Org, Data, Pheno, AState, EState>;

    public createOrganisms(n: number): Array<Organism<Gen, Pop, Org, Data, Pheno, AState, EState>> {
        return _.range(n)
            .map((i) => this.createOrganism(new Genome(this.genOptions), this.orgOptions));
    }

    // spawns and evenly distributes organisms across all envs
    public populate(
        organisms: Observer<Organism<Gen, Pop, Org, Data, Pheno, AState, EState>>,
        top: ReactiveCollection<IEvaluation<Gen, Data, Pheno>>,
    ): Subscription {
        const orgs = this.createOrganisms(this.popOptions.size);

        for (const o of orgs) {
            organisms.next(o);
        }

        return this
            .updateGenotype(this.evaluations, top)
            .map((genome) => this.createOrganism(genome, this.orgOptions))
            .subscribe(
                (o) => organisms.next(o),
                (error) => console.log(`population.populate(): ${error}`),
            );
    }

    // update genotypes as they are evaluated
    private updateGenotype(
        evaluations: Observable<IEvaluation<Gen, Data, Pheno>>,
        top: ReactiveCollection<IEvaluation<Gen, Data, Pheno>>): Observable<Genome<Gen>> {

        return evaluations
            .map((e) => {
                const update = chance.weighted(
                    [
                        this.mutateGenotype,
                        this.reproduceGenotype,
                        this.randomizeGenotype,
                    ],
                    [
                        this.popOptions.weights.mutate,
                        this.popOptions.weights.reproduce,
                        this.popOptions.weights.randomize,
                    ],
                );

                return update(e, top);
            });
    }

{'fraction_non_alphanumeric': 0.10127378518635005, 'fraction_numerical': 0.0003145148608271741, 'mean_word_length': 2.1469569520039586, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '494503', 'n_tokens_mistral': 1843, 'n_tokens_neox': 1713, 'n_words': 435}