pub fn construct<T, E>(module_spec: T, save_dir: Option<PathBuf>) -> anyhow::Result<Resolution<CCC>>
where
    anyhow::Error: From<E>,
    T: TryInto<Config, Error = E>,
{
    let Config {
        module: json,
        algebra,
    } = module_spec.try_into()?;

    let algebra = Arc::new(SteenrodAlgebra::from_json(&json, algebra)?);
    let module = Arc::new(FiniteModule::from_json(Arc::clone(&algebra), &json)?);
    let mut chain_complex = Arc::new(FiniteChainComplex::ccdz(Arc::clone(&module)));

    let cofiber = &json["cofiber"];
    if !cofiber.is_null() {
        use crate::chain_complex::ChainMap;
        use crate::yoneda::yoneda_representative;
        use algebra::module::homomorphism::FreeModuleHomomorphism;
        use algebra::module::BoundedModule;

        let s = cofiber["s"].as_u64().unwrap() as u32;
        let t = cofiber["t"].as_i64().unwrap() as i32;
        let idx = cofiber["idx"].as_u64().unwrap() as usize;

        let resolution = Resolution::new(Arc::clone(&chain_complex));
        resolution.compute_through_bidegree(s, t + module.max_degree());

        let map = FreeModuleHomomorphism::new(resolution.module(s), Arc::clone(&module), t);
        let mut new_output = fp::matrix::Matrix::new(
            module.prime(),
            resolution.module(s).number_of_gens_in_degree(t),
            1,
        );
        new_output[idx].set_entry(0, 1);

        map.add_generators_from_matrix_rows(t, new_output.as_slice_mut());
        map.extend_by_zero(module.max_degree() + t);

        let cm = ChainMap {
            s_shift: s,
            chain_maps: vec![map],
        };
        let yoneda = yoneda_representative(Arc::new(resolution), cm);
        let mut yoneda = FiniteChainComplex::from(yoneda);
        yoneda.pop();

        chain_complex = Arc::new(yoneda);
    }

    Resolution::new_with_save(chain_complex, save_dir)
}
/// This constructs a resolution resolving a module according to the specifications
///
/// # Arguments
///  - `module_spec`: A specification for the module. This is any object that implements
///     [`TryInto<Config>`] (with appropriate error bounds). In practice, we can supply
///     - A [`Config`] object itself
///     - `(json, algebra)`: The first argument is a [`serde_json::Value`] that specifies the
///       module; the second argument is either a string (`"milnor"` or `"adem"`) or an
///       [`algebra::AlgebraType`] object.
///     - `(module_name, algebra)`: The first argument is the name of the module and the second is
///       as above. Modules are searched in the current directory, `$CWD/steenrod_modules` and
///       `ext/steenrod_modules`. The modules can be shifted by appending e.g. `S_2[2]`.
///     - `module_spec`, a single `&str` of the form `module_name@algebra`, where `module_name` and
///       `algebra` are as above.
///  - `save_file`: The save file for the module. If it points to an invalid save file, an error is
///    returned.
This constructs a resolution resolving a module according to the specifications
This constructs a resolution resolving a module according to the specifications
pub fn construct<T, E>(module_spec: T, save_dir: Option<PathBuf>) -> anyhow::Result<Resolution<CCC>>
where
    anyhow::Error: From<E>,
    T: TryInto<Config, Error = E>,
{
    let Config {
        module: json,
        algebra,
    } = module_spec.try_into()?;
    let algebra = Arc::new(SteenrodAlgebra::from_json(&json, algebra)?);
    let module = Arc::new(FiniteModule::from_json(Arc::clone(&algebra), &json)?);
    let mut chain_complex = Arc::new(FiniteChainComplex::ccdz(Arc::clone(&module)));
    let cofiber = &json["cofiber"];
    if !cofiber.is_null() {
        use crate::chain_complex::ChainMap;
        use crate::yoneda::yoneda_representative;
        use algebra::module::homomorphism::FreeModuleHomomorphism;
        use algebra::module::BoundedModule;
        let s = cofiber["s"].as_u64().unwrap() as u32;
        let t = cofiber["t"].as_i64().unwrap() as i32;
        let idx = cofiber["idx"].as_u64().unwrap() as usize;
        let resolution = Resolution::new(Arc::clone(&chain_complex));
        resolution.compute_through_bidegree(s, t + module.max_degree());
        let map = FreeModuleHomomorphism::new(resolution.module(s), Arc::clone(&module), t);
        let mut new_output = fp::matrix::Matrix::new(
            module.prime(),
            resolution.module(s).number_of_gens_in_degree(t),
            1,
        );
        new_output[idx].set_entry(0, 1);
        map.add_generators_from_matrix_rows(t, new_output.as_slice_mut());
        map.extend_by_zero(module.max_degree() + t);
        let cm = ChainMap {
            s_shift: s,
            chain_maps: vec![map],
        };
        let yoneda = yoneda_representative(Arc::new(resolution), cm);
        let mut yoneda = FiniteChainComplex::from(yoneda);
        yoneda.pop();
        chain_complex = Arc::new(yoneda);
    }
    Resolution::new_with_save(chain_complex, save_dir)
}
pub fn construct < T , E > ( module_spec : T , save_dir : Option < PathBuf > ) -> anyhow :: Result < Resolution < CCC > > where anyhow :: Error : From < E > , T : TryInto < Config , Error = E > , { let Config { module : json , algebra , } = module_spec . try_into ( ) ? ; let algebra = Arc :: new ( SteenrodAlgebra :: from_json ( & json , algebra ) ? ) ; let module = Arc :: new ( FiniteModule :: from_json ( Arc :: clone ( & algebra ) , & json ) ? ) ; let mut chain_complex = Arc :: new ( FiniteChainComplex :: ccdz ( Arc :: clone ( & module ) ) ) ; let cofiber = & json [ " " ] ; if ! cofiber . is_null ( ) { use crate :: chain_complex :: ChainMap ; use crate :: yoneda :: yoneda_representative ; use algebra :: module :: homomorphism :: FreeModuleHomomorphism ; use algebra :: module :: BoundedModule ; let s = cofiber [ " " ] . as_u64 ( ) . unwrap ( ) as u32 ; let t = cofiber [ " " ] . as_i64 ( ) . unwrap ( ) as i32 ; let idx = cofiber [ " " ] . as_u64 ( ) . unwrap ( ) as usize ; let resolution = Resolution :: new ( Arc :: clone ( & chain_complex ) ) ; resolution . compute_through_bidegree ( s , t + module . max_degree ( ) ) ; let map = FreeModuleHomomorphism :: new ( resolution . module ( s ) , Arc :: clone ( & module ) , t ) ; let mut new_output = fp :: matrix :: Matrix :: new ( module . prime ( ) , resolution . module ( s ) . number_of_gens_in_degree ( t ) , 1 , ) ; new_output [ idx ] . set_entry ( 0 , 1 ) ; map . add_generators_from_matrix_rows ( t , new_output . as_slice_mut ( ) ) ; map . extend_by_zero ( module . max_degree ( ) + t ) ; let cm = ChainMap { s_shift : s , chain_maps : vec ! [ map ] , } ; let yoneda = yoneda_representative ( Arc :: new ( resolution ) , cm ) ; let mut yoneda = FiniteChainComplex :: from ( yoneda ) ; yoneda . pop ( ) ; chain_complex = Arc :: new ( yoneda ) ; } Resolution :: new_with_save ( chain_complex , save_dir ) }
This constructs a resolution resolving a module according to the specifications
This constructs a resolution resolving a module according to the specifications
module_spec
T
save_dir
Option<PathBuf>
module_spec
T
save_dir
Option<PathBuf>