commit 837efa1d3d072e3fa62f34b7a8e404b395f71131
parent f67c9f48161d67044517d657f74eb8113f0d89cc
Author: Joël Lupien (Jojolepro) <jojolepromain@gmail.com>
Date: Wed, 8 Aug 2018 19:23:54 -0400
Added LowerPartialFunction
Diffstat:
8 files changed, 365 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,3 @@
+/target/
+**/*.rs.bk
+Cargo.lock
diff --git a/.idea/misc.xml b/.idea/misc.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="CargoProjects">
+ <cargoProject FILE="$PROJECT_DIR$/Cargo.toml" />
+ </component>
+ <component name="RustProjectSettings">
+ <option name="toolchainHomeDirectory" value="/usr/bin" />
+ </component>
+</project>+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ProjectModuleManager">
+ <modules>
+ <module fileurl="file://$PROJECT_DIR$/.idea/partial_function.iml" filepath="$PROJECT_DIR$/.idea/partial_function.iml" />
+ </modules>
+ </component>
+</project>+
\ No newline at end of file
diff --git a/.idea/partial_function.iml b/.idea/partial_function.iml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$" />
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module>+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="VcsDirectoryMappings">
+ <mapping directory="" vcs="Git" />
+ </component>
+</project>+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
@@ -0,0 +1,253 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ChangeListManager">
+ <list default="true" id="c61cb26e-cd20-4478-b386-32735fce1844" name="Default" comment="">
+ <change afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
+ <change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/lib.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/lib.rs" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/tests/tests.rs" beforeDir="false" afterPath="$PROJECT_DIR$/tests/tests.rs" afterDir="false" />
+ </list>
+ <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
+ <option name="TRACKING_ENABLED" value="true" />
+ <option name="SHOW_DIALOG" value="false" />
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+ <option name="LAST_RESOLUTION" value="IGNORE" />
+ </component>
+ <component name="FileEditorManager">
+ <leaf>
+ <file leaf-file-name="lib.rs" pinned="false" current-in-tab="true">
+ <entry file="file://$PROJECT_DIR$/src/lib.rs">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="348">
+ <caret line="153" column="13" lean-forward="true" selection-start-line="153" selection-start-column="13" selection-end-line="153" selection-end-column="13" />
+ <folding>
+ <element signature="e#4017#4018#0" expanded="true" />
+ <element signature="e#4066#4067#0" expanded="true" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="tests.rs" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/tests/tests.rs">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="1068">
+ <caret line="99" column="29" selection-start-line="99" selection-start-column="29" selection-end-line="99" selection-end-column="29" />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name=".gitignore" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/.gitignore">
+ <provider selected="true" editor-type-id="text-editor" />
+ </entry>
+ </file>
+ </leaf>
+ </component>
+ <component name="Git.Settings">
+ <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+ </component>
+ <component name="IdeDocumentHistory">
+ <option name="CHANGED_PATHS">
+ <list>
+ <option value="$PROJECT_DIR$/tests/tests.rs" />
+ <option value="$PROJECT_DIR$/src/lib.rs" />
+ </list>
+ </option>
+ </component>
+ <component name="ProjectFrameBounds">
+ <option name="x" value="12" />
+ <option name="y" value="15" />
+ <option name="width" value="1896" />
+ <option name="height" value="1053" />
+ </component>
+ <component name="ProjectLevelVcsManager">
+ <ConfirmationsSetting value="2" id="Add" />
+ </component>
+ <component name="ProjectView">
+ <navigator proportions="" version="1">
+ <foldersAlwaysOnTop value="true" />
+ </navigator>
+ <panes>
+ <pane id="PackagesPane" />
+ <pane id="Scope" />
+ <pane id="AndroidView" />
+ <pane id="ProjectPane">
+ <subPane>
+ <expand>
+ <path>
+ <item name="partial_function" type="b2602c69:ProjectViewProjectNode" />
+ <item name="partial_function" type="462c0819:PsiDirectoryNode" />
+ </path>
+ <path>
+ <item name="partial_function" type="b2602c69:ProjectViewProjectNode" />
+ <item name="partial_function" type="462c0819:PsiDirectoryNode" />
+ <item name="src" type="462c0819:PsiDirectoryNode" />
+ </path>
+ <path>
+ <item name="partial_function" type="b2602c69:ProjectViewProjectNode" />
+ <item name="partial_function" type="462c0819:PsiDirectoryNode" />
+ <item name="tests" type="462c0819:PsiDirectoryNode" />
+ </path>
+ </expand>
+ <select />
+ </subPane>
+ </pane>
+ </panes>
+ </component>
+ <component name="PropertiesComponent">
+ <property name="last_opened_file_path" value="$PROJECT_DIR$" />
+ <property name="org.rust.cargo.project.model.PROJECT_DISCOVERY" value="true" />
+ </component>
+ <component name="RunDashboard">
+ <option name="ruleStates">
+ <list>
+ <RuleState>
+ <option name="name" value="ConfigurationTypeDashboardGroupingRule" />
+ </RuleState>
+ <RuleState>
+ <option name="name" value="StatusDashboardGroupingRule" />
+ </RuleState>
+ </list>
+ </option>
+ </component>
+ <component name="RunManager">
+ <configuration default="true" type="Application" factoryName="Application">
+ <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+ </configuration>
+ <configuration default="true" type="JUnit" factoryName="JUnit">
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <option name="PACKAGE_NAME" />
+ <option name="MAIN_CLASS_NAME" />
+ <option name="METHOD_NAME" />
+ <option name="TEST_OBJECT" value="class" />
+ <option name="VM_PARAMETERS" value="-ea" />
+ <option name="PARAMETERS" />
+ <option name="WORKING_DIRECTORY" value="%MODULE_WORKING_DIR%" />
+ <option name="PASS_PARENT_ENVS" value="true" />
+ <option name="TEST_SEARCH_SCOPE">
+ <value defaultName="singleModule" />
+ </option>
+ <patterns />
+ </configuration>
+ <configuration default="true" type="TestNG" factoryName="TestNG">
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <option name="SUITE_NAME" />
+ <option name="PACKAGE_NAME" />
+ <option name="MAIN_CLASS_NAME" />
+ <option name="METHOD_NAME" />
+ <option name="GROUP_NAME" />
+ <option name="TEST_OBJECT" value="CLASS" />
+ <option name="VM_PARAMETERS" value="-ea" />
+ <option name="PARAMETERS" />
+ <option name="WORKING_DIRECTORY" value="%MODULE_WORKING_DIR%" />
+ <option name="OUTPUT_DIRECTORY" />
+ <option name="PASS_PARENT_ENVS" value="true" />
+ <option name="TEST_SEARCH_SCOPE">
+ <value defaultName="singleModule" />
+ </option>
+ <option name="USE_DEFAULT_REPORTERS" value="false" />
+ <option name="PROPERTIES_FILE" />
+ <properties />
+ <listeners />
+ </configuration>
+ </component>
+ <component name="SbtLocalSettings">
+ <option name="projectSyncType">
+ <map>
+ <entry key="$PROJECT_DIR$/../../HoppinWorldBackend" value="PREVIEW" />
+ <entry key="$PROJECT_DIR$/../../gamestatx_backend/gamestatx_backend" value="PREVIEW" />
+ </map>
+ </option>
+ </component>
+ <component name="SvnConfiguration">
+ <configuration />
+ </component>
+ <component name="TaskManager">
+ <task active="true" id="Default" summary="Default task">
+ <changelist id="c61cb26e-cd20-4478-b386-32735fce1844" name="Default" comment="" />
+ <created>1533767911688</created>
+ <option name="number" value="Default" />
+ <option name="presentableId" value="Default" />
+ <updated>1533767911688</updated>
+ </task>
+ <servers />
+ </component>
+ <component name="ToolWindowManager">
+ <frame x="12" y="15" width="1896" height="1053" extended-state="0" />
+ <editor active="true" />
+ <layout>
+ <window_info anchor="right" id="Palette" />
+ <window_info anchor="bottom" id="TODO" order="6" />
+ <window_info anchor="right" id="Cargo" />
+ <window_info anchor="right" id="Palette	" />
+ <window_info id="Image Layers" />
+ <window_info anchor="right" id="Capture Analysis" />
+ <window_info anchor="bottom" id="Event Log" side_tool="true" />
+ <window_info anchor="right" id="Maven Projects" />
+ <window_info anchor="bottom" id="Version Control" />
+ <window_info anchor="bottom" id="Run" order="2" />
+ <window_info anchor="bottom" id="Terminal" />
+ <window_info id="Capture Tool" />
+ <window_info id="Designer" />
+ <window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.121081084" />
+ <window_info id="Structure" order="1" side_tool="true" weight="0.25" />
+ <window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
+ <window_info id="UI Designer" />
+ <window_info anchor="right" id="Theme Preview" />
+ <window_info id="Favorites" side_tool="true" />
+ <window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
+ <window_info anchor="bottom" id="Find" order="1" />
+ <window_info anchor="right" id="Commander" order="0" weight="0.4" />
+ <window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
+ <window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
+ <window_info anchor="bottom" id="Message" order="0" />
+ <window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
+ </layout>
+ </component>
+ <component name="VcsContentAnnotationSettings">
+ <option name="myLimit" value="2678400000" />
+ </component>
+ <component name="editorHistoryManager">
+ <entry file="file://$PROJECT_DIR$/.gitignore">
+ <provider selected="true" editor-type-id="text-editor" />
+ </entry>
+ <entry file="file://$PROJECT_DIR$/tests/tests.rs">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="1068">
+ <caret line="99" column="29" selection-start-line="99" selection-start-column="29" selection-end-line="99" selection-end-column="29" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/lib.rs">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="348">
+ <caret line="153" column="13" lean-forward="true" selection-start-line="153" selection-start-column="13" selection-end-line="153" selection-end-column="13" />
+ <folding>
+ <element signature="e#4017#4018#0" expanded="true" />
+ <element signature="e#4066#4067#0" expanded="true" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ </component>
+ <component name="masterDetails">
+ <states>
+ <state key="ProjectJDKs.UI">
+ <settings>
+ <last-edited>1.8</last-edited>
+ <splitter-proportions>
+ <option name="proportions">
+ <list>
+ <option value="0.2" />
+ </list>
+ </option>
+ </splitter-proportions>
+ </settings>
+ </state>
+ </states>
+ </component>
+</project>+
\ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
@@ -37,7 +37,7 @@ where
}
/// Evaluates the partial function.
- /// Returns NAN if no function is defined.
+ /// Returns None if no function is defined.
pub fn eval(&self, x: B) -> Option<O> {
let iter = self.funcs.iter().enumerate();
for (i, bounded) in iter {
@@ -104,6 +104,7 @@ where
}
+/// A lower bounded function is a function that is valid from [x..infinite[, or until it hits another function's start.
struct LowerBoundedFunction<B, O>
where
B: PartialOrd,
@@ -114,6 +115,17 @@ where
pub lower: B,
}
+
+/// A lower partial function is a function that is defined by segments valid from [x..infinite[, or until it hits another function's start.
+/// It starts searching at -infinity and goes up to infinity, and takes the last seen function that contains the desired invariable value (x).
+///
+/// Example:
+/// [0..infinity[ = 5
+/// [1..infinity[ = 10
+///
+/// f(0.5) = 5
+/// f(1) = 10
+/// f(70) = 10
pub struct LowerPartialFunction<B, O>
where
B: PartialOrd,
@@ -121,6 +133,30 @@ where
funcs: Vec<LowerBoundedFunction<B, O>>,
}
+impl<B, O> LowerPartialFunction<B, O>
+where
+ B: PartialOrd,
+{
+ /// Creates a new LowerPartialFunctionBuilder.
+ pub fn new() -> LowerPartialFunctionBuilder<B, O> {
+ LowerPartialFunctionBuilder::new()
+ }
+
+ /// Evaluates the partial function.
+ /// Returns None if no function is defined for the searched invariable value (x).
+ pub fn eval(&self, x: B) -> Option<O> {
+ let iter = self.funcs.iter().enumerate();
+ for (i, bounded) in iter {
+ let next = self.funcs.get(i + 1);
+ if x >= bounded.lower && ((next.is_some() && next.unwrap().lower > x) || next.is_none()){
+ let f = bounded.func;
+ return Some(f(x));
+ }
+ }
+ None
+ }
+}
+
/// A builder to create an immutable PartialFunction.
pub struct LowerPartialFunctionBuilder<B, O>
where
diff --git a/tests/tests.rs b/tests/tests.rs
@@ -80,4 +80,39 @@ mod tests {
.with(0.0, 1.0, |x| 5.0)
.build();
}
+
+ #[test]
+ fn lower_partial_normal() {
+ let f = LowerPartialFunction::new()
+ .with(0.0, |x| 1)
+ .with(1.0, |x| 2)
+ .build();
+ assert_eq!(f.eval(-1.0),None);
+ assert_eq!(f.eval(0.0),Some(1));
+ assert_eq!(f.eval(0.5),Some(1));
+ assert_eq!(f.eval(1.0),Some(2));
+ assert_eq!(f.eval(1000.0),Some(2));
+ }
+
+ #[test]
+ fn lower_partial_inverse_insert() {
+ let f = LowerPartialFunction::new()
+ .with(1.0, |x| 2)
+ .with(0.0, |x| 1)
+ .build();
+ assert_eq!(f.eval(-1.0),None);
+ assert_eq!(f.eval(0.0),Some(1));
+ assert_eq!(f.eval(0.5),Some(1));
+ assert_eq!(f.eval(1.0),Some(2));
+ assert_eq!(f.eval(1000.0),Some(2));
+ }
+
+ #[test]
+ #[should_panic]
+ fn lower_partial_overlap() {
+ let f = LowerPartialFunction::new()
+ .with(0.0, |x| 1)
+ .with(0.0, |x| 2)
+ .build();
+ }
}