diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index e0b8986..e0b44c9 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -1,78 +1,76 @@
-# This workflow creates the deployement on github.
+# This workflow manages the deployement of BRIDGES:
+# - NuGet Package for relevant branches (see "deploy-package" environment)
+# - Pre-Release and Release for release and master branches, respectively
name: Deploy
-# Controls the event triggering the workflow
-on:
- # Gives the possibility to trigger the workflow manually.
- workflow_dispatch:
- inputs:
- version:
- description: 'Package Version: v[Major].[Minor].[Patch]'
- required: true
- type: string
-
-env:
- # Path of the Project being Tested and Packaged.
- PROJECT_PATH: 'BRIDGES/BRIDGES.csproj'
- # Output directory for the NuGet Package
- PKG_OUTPUT_DIR: ${{ github.workspace }}/output
- # URL of the GitHub Package Repository
- NUGET_SRC_URL: https://nuget.pkg.github.com/bridges-libraries/index.json
+on: # Controls the event triggering the workflow
+ workflow_dispatch: # The workflow can be triggered manually.
+
+env: # Environment variable shared among the jobs
+ PKG_OUTPUT_DIR: ${{ github.workspace }}/output # Output directory for the NuGet Package
- # Token automatically generated by GitHub for the workflow
- GITHUB_TOKEN: ${{ github.token }}
-
jobs:
- # Verify the inputs & Set up the workflow
- verify_inputs:
-
- runs-on : ubuntu-latest
-
- # Map a step output to a job output
+ manage_version:
+ runs-on: ubuntu-latest # Specify the runner os
+ environment: versioning # Specify the protection rules, variables and secrets
outputs:
- version_number : ${{ steps.verify-version.outputs.PKG_VERSION_NUMBER }}
-
+ pkg_version: ${{ steps.create-version.outputs.PKG_VERSION }}
+ pkg_release_type: ${{ steps.create-version.outputs.PKG_RELEASE_TYPE }}
steps:
- - name: Verify branch
+ # Get the repository variable and Increment the version
+ - name: Select and Increment version
+ id: create-version
shell: bash
run: |
- if [[ ${{github.ref}} =~ .*master$ ]]
- then
- echo "The reference branch is 'master'"
- elif [[ ${{github.ref}} =~ ^.*/release/.*$ ]]
- then
- echo "The reference branch is 'release'"
- elif [[ ${{github.ref}} =~ .*develop$ ]]
- then
- echo "The reference branch is 'develop'"
- else
- exit 1
- fi
- - name: Verify version & Get version number
- id: verify-version
- shell: bash
- run : |
- version=${{inputs.version}}
- if [[ ${version} =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]
- then
- echo "PKG_VERSION_NUMBER=${version:1}" >> $GITHUB_OUTPUT
- else
- echo "The package version must start with 'v'."
- exit 1
+ version=${{vars.VERSION}} # Get the current package version
+ numbers=( ${version//./ } ) # Split into array to get version numbers
+ if [[ ${{github.ref}} =~ .*master$ ]]; then # For master branch
+ ((numbers[0]++)) # Increment the major version number
+ version="${numbers[0]}.0.0"
+ echo "PKG_VERSION=$version" >> $GITHUB_OUTPUT
+ echo "PKG_RELEASE_TYPE=" >> $GITHUB_OUTPUT
+ elif [[ ${{github.ref}} =~ ^.*/release/.*$ ]]; then # For release branches
+ ((numbers[1]++)) # Increment the minor version number
+ version="${numbers[0]}.${numbers[1]}.0"
+ echo "PKG_VERSION=$version" >> $GITHUB_OUTPUT
+ echo "PKG_RELEASE_TYPE=" >> $GITHUB_OUTPUT
+ elif [[ ${{github.ref}} =~ .*develop$ ]]; then # For release branch
+ ((numbers[2]++)) # Increment the patch version number
+ version="${numbers[0]}.${numbers[1]}.${numbers[2]}"
+ echo "PKG_VERSION=$version" >> $GITHUB_OUTPUT
+ echo "PKG_RELEASE_TYPE=-alpha" >> $GITHUB_OUTPUT
+ else # For feature branches
+ ((numbers[2]++)) # Increment the patch version number
+ version="${numbers[0]}.${numbers[1]}.${numbers[2]}"
+ echo "PKG_VERSION=$version" >> $GITHUB_OUTPUT
+ echo "PKG_RELEASE_TYPE=-beta" >> $GITHUB_OUTPUT
fi
-
- # Build the NuGet package & Publish it on GitHub Packages
- deploy_package:
- needs : verify_inputs
-
- runs-on : ubuntu-latest
-
+ # Generate a temporary token for the Github App
+ - name: Generate a GitHub App token
+ id: generate-token
+ uses: actions/create-github-app-token@v1
+ with:
+ app-id: ${{ secrets.VARIABLES_GITHUB_APP_ID }}
+ private-key: ${{ secrets.VARIABLES_GITHUB_APP_PRIVATE_KEY }}
+ # Update the repository variable
+ - name: Update version variable
+ env:
+ VAR_NAME: 'VERSION'
+ VAR_VALUE: ${{ steps.create-version.outputs.PKG_VERSION }}
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
+ run: |
+ gh api --method PATCH -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \
+ /repos/${{github.repository}}/actions/variables/${{env.VAR_NAME}} -f name='${{env.VAR_NAME}}' -f value='${{env.VAR_VALUE}}'
+
+ nuget_packaging:
+ needs : manage_version # Specify jobs needed to run this one
+ runs-on : ubuntu-latest # Specify the runner os
steps:
# Check-out the branch
- name: Check-out Branch
uses: actions/checkout@v3
# Setup the .Net environment
- - name: Check-out Branch
+ - name: Setup .Net environmnent
uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.0.x
@@ -84,39 +82,44 @@ jobs:
run: dotnet test --verbosity normal
# Pack the project in a NuGet package
- name: Create NuGet
+ env:
+ PACKAGE_ID: 'BRIDGES'
run: |
- if [[ ${{github.ref}} =~ .*master$ ]]
- then
- dotnet pack ${{env.PROJECT_PATH}} -p:PackageId='BRIDGES' -p:PackageVersion=${{needs.verify_inputs.outputs.version_number}} -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg --output ${{ env.PKG_OUTPUT_DIR }}
- elif [[ ${{github.ref}} =~ ^.*/release/.*$ ]]
- then
- dotnet pack ${{env.PROJECT_PATH}} -p:PackageId='BRIDGES' -p:PackageVersion=${{needs.verify_inputs.outputs.version_number}}-beta -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg --output ${{ env.PKG_OUTPUT_DIR }}
- elif [[ ${{github.ref}} =~ .*develop$ ]]
- then
- dotnet pack ${{env.PROJECT_PATH}} -p:PackageId='BRIDGES-Dev' -p:PackageVersion=${{needs.verify_inputs.outputs.version_number}}-beta -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg --output ${{ env.PKG_OUTPUT_DIR }}
- else
- echo "::error file=deploy.yml,line=94,col=9,endColumn=13::Wrong branch for deployement"
- exit 1
- fi
-
- # Publish the NuGet package on GitHub
- - name: Publish NuGet Package
- run: |
- dotnet nuget push ${{ env.PKG_OUTPUT_DIR }}/*.nupkg --api-key ${{ env.GITHUB_TOKEN }} --source ${{ env.NUGET_SRC_URL }}
- dotnet nuget push ${{ env.PKG_OUTPUT_DIR }}/*.snupkg --api-key ${{ env.GITHUB_TOKEN }} --source ${{ env.NUGET_SRC_URL }}
+ dotnet pack ${{vars.PROJECT_PATH}} -p:PackageId=${{ env.PACKAGE_ID }} \
+ -p:PackageVersion=${{ needs.manage_version.outputs.PKG_VERSION }}${{ needs.manage_version.outputs.PKG_RELEASE_TYPE }} \
+ -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg \
+ --output ${{ env.PKG_OUTPUT_DIR }}
# Upload the artefacts (Package and Symbols)
- name: Upload Github Artifacts
uses: actions/upload-artifact@v3
with:
name: package
path: ${{ env.PKG_OUTPUT_DIR }}/*
-
- # Tag the commit with the package version
- tag_commit:
- needs : deploy_package
-
- runs-on : ubuntu-latest
-
+
+ publish_nuget:
+ needs : nuget_packaging # Specify jobs needed to run this one
+ runs-on : ubuntu-latest # Specify the runner os
+ steps:
+ # Setup the .Net environment
+ - name: Setup .Net environmnent
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: 6.0.x
+ # Download the artefacts (Package and Symbols)
+ - name: Download Github Artifacts
+ uses: actions/download-artifact@v3
+ with:
+ name: package
+ path: ${{ env.PKG_OUTPUT_DIR }}/
+ # Publish the NuGet package on GitHub
+ - name: Publish NuGet Package
+ run: |
+ dotnet nuget push ${{ env.PKG_OUTPUT_DIR }}/*.nupkg --api-key ${{ github.token }} --source ${{ vars.NUGET_SRC_URL }}
+ dotnet nuget push ${{ env.PKG_OUTPUT_DIR }}/*.snupkg --api-key ${{ github.token }} --source ${{ vars.NUGET_SRC_URL }}
+
+ create_tag:
+ needs: [manage_version, nuget_packaging] # Specify jobs needed to run this one
+ runs-on : ubuntu-latest # Specify the runner os
steps:
# Create a tag on the latest commit of the branch
- name: Create tag
@@ -126,16 +129,15 @@ jobs:
github.rest.git.createRef({
owner: context.repo.owner,
repo: context.repo.repo,
- ref: 'refs/tags/${{inputs.version}}',
+ ref: 'refs/tags/v${{ needs.manage_version.outputs.PKG_VERSION }}${{ needs.manage_version.outputs.PKG_RELEASE_TYPE }}',
sha: context.sha
})
-
- # Create a (Pre-)Release on Github
- release_package:
- needs : tag_commit
- if : ${{ endsWith( github.ref , 'master') || contains( github.ref , '/release/') }}
-
+
+ create_release:
+ needs : [manage_version, create_tag]
runs-on : ubuntu-latest
+
+ if : ${{ endsWith( github.ref , 'master') || contains( github.ref , '/release/') }}
steps:
# Download the artefacts (Package and Symbols)
@@ -148,21 +150,15 @@ jobs:
- name: Evaluate if Pre-Release
shell: bash
run : |
- if [[ ${{github.ref}} =~ .*master$ ]]
- then
+ if [[ ${{github.ref}} =~ .*master$ ]]; then
echo "IS_PRERELEASE=false" >> $GITHUB_ENV
- elif [[ ${{github.ref}} =~ ^.*/release/.*$ ]]
- then
- echo "IS_PRERELEASE=true" >> $GITHUB_ENV
else
- echo "The package should not be released."
- exit 1
+ echo "IS_PRERELEASE=true" >> $GITHUB_ENV
fi
# Publish the Release
- name: Publish Release
uses: ncipollo/release-action@v1
with :
- prerelease : ${{env.IS_PRERELEASE}}
+ prerelease : ${{ env.IS_PRERELEASE }}
artifacts: ${{ env.PKG_OUTPUT_DIR }}/*
- tag : ${{inputs.version}}
-
+ tag : ${{ needs.manage_version.outputs.PKG_VERSION }}${{ needs.manage_version.outputs.PKG_RELEASE_TYPE }}
\ No newline at end of file
diff --git a/BRIDGES/Serialisation/Deserialise.DataStructures.cs b/BRIDGES/Serialisation/Deserialise.DataStructures.cs
index 3a76b6a..5ec52b5 100644
--- a/BRIDGES/Serialisation/Deserialise.DataStructures.cs
+++ b/BRIDGES/Serialisation/Deserialise.DataStructures.cs
@@ -21,18 +21,18 @@ public static partial class Deserialise
/// The deserialised from the string representation.
/// The specified file format for the halfedge mesh deserialisation is not implemented.
[Deserialiser(typeof(Meshes.HalfedgeMesh.Mesh<>))]
- public static Meshes.HalfedgeMesh.Mesh HalfedgeMesh(string text, PolyhedralMeshSerialisationFormat format)
+ public static Meshes.HalfedgeMesh.Mesh HalfedgeMesh(string text, Formats.PolyhedralMeshSerialisationFormat format)
where TPosition : IEquatable,
Algebra.Fundamentals.IAddable /* To Do : Remove */,
Algebra.Sets.IGroupAction
{
switch (format)
{
- case PolyhedralMeshSerialisationFormat.Json:
+ case Formats.PolyhedralMeshSerialisationFormat.Json:
return HalfedgeMeshFromJson(text);
- case PolyhedralMeshSerialisationFormat.Xml:
+ case Formats.PolyhedralMeshSerialisationFormat.Xml:
throw new NotImplementedException();
- case PolyhedralMeshSerialisationFormat.Obj:
+ case Formats.PolyhedralMeshSerialisationFormat.Obj:
throw new NotImplementedException();
default:
throw new NotImplementedException("The specified file format for the halfedge mesh deserialisation is not implemented.");
@@ -47,18 +47,18 @@ public static Meshes.HalfedgeMesh.Mesh HalfedgeMesh(string
/// Format of the serialisation.
/// The deserialised from the string representation.
[Deserialiser(typeof(Meshes.FaceVertexMesh.Mesh<>))]
- public static Meshes.FaceVertexMesh.Mesh FaceVertexMesh(string text, PolyhedralMeshSerialisationFormat format)
+ public static Meshes.FaceVertexMesh.Mesh FaceVertexMesh(string text, Formats.PolyhedralMeshSerialisationFormat format)
where TPosition : IEquatable,
Algebra.Fundamentals.IAddable /* To Do : Remove */,
Algebra.Sets.IGroupAction
{
switch (format)
{
- case PolyhedralMeshSerialisationFormat.Json:
+ case Formats.PolyhedralMeshSerialisationFormat.Json:
throw new NotImplementedException();
- case PolyhedralMeshSerialisationFormat.Xml:
+ case Formats.PolyhedralMeshSerialisationFormat.Xml:
throw new NotImplementedException();
- case PolyhedralMeshSerialisationFormat.Obj:
+ case Formats.PolyhedralMeshSerialisationFormat.Obj:
throw new NotImplementedException();
default:
throw new NotImplementedException("The specified file format for the face|vertex mesh deserialisation is not implemented.");
diff --git a/BRIDGES/Serialisation/Formats/PolyhedralMeshFormat.cs b/BRIDGES/Serialisation/Formats/PolyhedralMeshFormat.cs
index a82f223..f21b0d8 100644
--- a/BRIDGES/Serialisation/Formats/PolyhedralMeshFormat.cs
+++ b/BRIDGES/Serialisation/Formats/PolyhedralMeshFormat.cs
@@ -1,9 +1,7 @@
-using BRIDGES.Serialisation.Formats;
-using System;
-using System.Collections.Generic;
-using System.Text;
+using System;
-namespace BRIDGES.Serialisation
+
+namespace BRIDGES.Serialisation.Formats
{
///
/// Specifies the file formats available for the meshes.
diff --git a/BRIDGES/Serialisation/Serialise.DataStructures.cs b/BRIDGES/Serialisation/Serialise.DataStructures.cs
index db68ca6..a04f6f1 100644
--- a/BRIDGES/Serialisation/Serialise.DataStructures.cs
+++ b/BRIDGES/Serialisation/Serialise.DataStructures.cs
@@ -21,18 +21,18 @@ public static partial class Serialise
/// Format of the serialisation.
/// A string representation of the .
[Serialiser(typeof(Meshes.HalfedgeMesh.Mesh<>))]
- public static string HalfedgeMesh(Meshes.HalfedgeMesh.Mesh mesh, PolyhedralMeshSerialisationFormat format)
+ public static string HalfedgeMesh(Meshes.HalfedgeMesh.Mesh mesh, Formats.PolyhedralMeshSerialisationFormat format)
where TPosition : IEquatable,
Algebra.Fundamentals.IAddable /* To Do : Remove */,
Algebra.Sets.IGroupAction
{
switch (format)
{
- case PolyhedralMeshSerialisationFormat.Json:
+ case Formats.PolyhedralMeshSerialisationFormat.Json:
return HalfedgeMeshToJson(mesh);
- case PolyhedralMeshSerialisationFormat.Xml:
+ case Formats.PolyhedralMeshSerialisationFormat.Xml:
throw new NotImplementedException();
- case PolyhedralMeshSerialisationFormat.Obj:
+ case Formats.PolyhedralMeshSerialisationFormat.Obj:
return PolyhedralMeshToObj(mesh);
default:
throw new NotImplementedException("The specified file format for the halfedge mesh serialisation is not implemented.");
@@ -47,18 +47,18 @@ public static string HalfedgeMesh(Meshes.HalfedgeMesh.Mesh
/// Format of the serialisation.
/// A string representation of the .
[Serialiser(typeof(Meshes.FaceVertexMesh.Mesh<>))]
- public static string FaceVertexMesh(Meshes.FaceVertexMesh.Mesh mesh, PolyhedralMeshSerialisationFormat format)
+ public static string FaceVertexMesh(Meshes.FaceVertexMesh.Mesh mesh, Formats.PolyhedralMeshSerialisationFormat format)
where TPosition : IEquatable,
Algebra.Fundamentals.IAddable /* To Do : Remove */,
Algebra.Sets.IGroupAction
{
switch (format)
{
- case PolyhedralMeshSerialisationFormat.Json:
+ case Formats.PolyhedralMeshSerialisationFormat.Json:
throw new NotImplementedException();
- case PolyhedralMeshSerialisationFormat.Xml:
+ case Formats.PolyhedralMeshSerialisationFormat.Xml:
throw new NotImplementedException();
- case PolyhedralMeshSerialisationFormat.Obj:
+ case Formats.PolyhedralMeshSerialisationFormat.Obj:
return PolyhedralMeshToObj(mesh);
default:
throw new NotImplementedException("The specified file format for the face|vertex mesh serialisation is not implemented.");
@@ -73,18 +73,18 @@ public static string FaceVertexMesh(Meshes.FaceVertexMesh.Mesh to serialise.
/// Format of the serialisation.
/// A string representation of the .
- public static string PolyhedralMesh(Meshes.IMesh mesh, PolyhedralMeshSerialisationFormat format)
+ public static string PolyhedralMesh(Meshes.IMesh mesh, Formats.PolyhedralMeshSerialisationFormat format)
where TPosition : IEquatable,
Algebra.Fundamentals.IAddable /* To Do : Remove */,
Algebra.Sets.IGroupAction
{
switch (format)
{
- case PolyhedralMeshSerialisationFormat.Json:
+ case Formats.PolyhedralMeshSerialisationFormat.Json:
throw new NotImplementedException();
- case PolyhedralMeshSerialisationFormat.Xml:
+ case Formats.PolyhedralMeshSerialisationFormat.Xml:
throw new NotImplementedException();
- case PolyhedralMeshSerialisationFormat.Obj:
+ case Formats.PolyhedralMeshSerialisationFormat.Obj:
return PolyhedralMeshToObj(mesh);
default:
throw new NotImplementedException("The specified file format for the polyhedral mesh serialisation is not implemented.");
diff --git a/BRIDGES/Solvers/GuidedProjection/Interfaces/IQuadraticConstraintType.cs b/BRIDGES/Solvers/GuidedProjection/Abstracts/ConstraintType.cs
similarity index 61%
rename from BRIDGES/Solvers/GuidedProjection/Interfaces/IQuadraticConstraintType.cs
rename to BRIDGES/Solvers/GuidedProjection/Abstracts/ConstraintType.cs
index 237c7c7..ab7f8ae 100644
--- a/BRIDGES/Solvers/GuidedProjection/Interfaces/IQuadraticConstraintType.cs
+++ b/BRIDGES/Solvers/GuidedProjection/Abstracts/ConstraintType.cs
@@ -4,29 +4,29 @@
using BRIDGES.LinearAlgebra.Matrices;
-namespace BRIDGES.Solvers.GuidedProjection.Interfaces
+namespace BRIDGES.Solvers.GuidedProjection.Abstracts
{
///
- /// Interface defining a quadratic constraint type for the .
+ /// Abstract class defining a constraint type.
///
- public interface IQuadraticConstraintType
+ public abstract class ConstraintType
{
#region Properties
///
/// Gets the local symmetric matrix Hi of the energy.
///
- SparseMatrix LocalHi { get; }
+ public SparseMatrix LocalHi { get; protected set; }
///
/// Gets the local vector Bi of the energy.
///
- SparseVector LocalBi { get; }
+ public SparseVector LocalBi { get; protected set; }
///
/// Gets the scalar value Ci of the energy.
///
- double Ci { get; }
+ public double Ci { get; protected set; }
#endregion
}
diff --git a/BRIDGES/Solvers/GuidedProjection/Abstracts/EnergyType.cs b/BRIDGES/Solvers/GuidedProjection/Abstracts/EnergyType.cs
new file mode 100644
index 0000000..ba40555
--- /dev/null
+++ b/BRIDGES/Solvers/GuidedProjection/Abstracts/EnergyType.cs
@@ -0,0 +1,27 @@
+using System;
+
+using BRIDGES.LinearAlgebra.Vectors;
+
+
+namespace BRIDGES.Solvers.GuidedProjection.Abstracts
+{
+ ///
+ /// Abstract class defining an energy type.
+ ///
+ public abstract class EnergyType
+ {
+ #region Properties
+
+ ///
+ /// Gets the local vector Ki of this energy.
+ ///
+ public SparseVector LocalKi { get; protected set; }
+
+ ///
+ /// Gets the scalar value Si of this energy.
+ ///
+ public double Si { get; protected set; }
+
+ #endregion
+ }
+}
diff --git a/BRIDGES/Solvers/GuidedProjection/Abstracts/LinearisedConstraintType.cs b/BRIDGES/Solvers/GuidedProjection/Abstracts/LinearisedConstraintType.cs
new file mode 100644
index 0000000..d457385
--- /dev/null
+++ b/BRIDGES/Solvers/GuidedProjection/Abstracts/LinearisedConstraintType.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+
+
+namespace BRIDGES.Solvers.GuidedProjection.Abstracts
+{
+ ///
+ /// Abstract class defining a linearised constraint type.
+ ///
+ public abstract class LinearisedConstraintType : ConstraintType
+ {
+ #region Methods
+
+ ///
+ /// Updates the local members (i.e. LocalHi and LocalBi) and the value Ci of the linearised constraint using the local variables.
+ ///
+ /// Actualised value of the constraint's local variables.
+ public abstract void UpdateLocal(IReadOnlyList variables);
+
+ #endregion
+ }
+}
diff --git a/BRIDGES/Solvers/GuidedProjection/Constraint.cs b/BRIDGES/Solvers/GuidedProjection/Constraint.cs
new file mode 100644
index 0000000..e849a44
--- /dev/null
+++ b/BRIDGES/Solvers/GuidedProjection/Constraint.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+
+using BRIDGES.Solvers.GuidedProjection.Abstracts;
+
+
+namespace BRIDGES.Solvers.GuidedProjection
+{
+ ///
+ /// Class defining a quadratic constraint for the .
+ ///
+ public sealed class Constraint
+ {
+ #region Fields
+
+ ///
+ /// Variables composing the local vector localX on which the is defined.
+ ///
+ private readonly Variable[] _variables;
+
+ #endregion
+
+ #region Properties
+
+ /// ///
+ /// Gets the constraint type defining the local matrix , the local vector and the scalar value .
+ ///
+ public ConstraintType Type { get; private set; }
+
+ ///
+ /// Gets the variables composing the local vector localX.
+ ///
+ public IReadOnlyList Variables => _variables;
+
+
+ ///
+ /// Gets or sets the weight of this constraint.
+ ///
+ public double Weight { get; internal set; }
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Initialises a new instance of the class.
+ ///
+ /// Constraint type defining the local quantities of this constraint.
+ /// Variables composing the local vector localX on which the local symmetric matrix Hi and the local vector Bi are defined.
+ /// Weight of this constraint.
+ public Constraint(ConstraintType constraintType, IReadOnlyList variables, double weight)
+ {
+ this.Type = constraintType;
+
+ this._variables = new Variable[variables.Count];
+ for (int i = 0; i < variables.Count; i++)
+ {
+ _variables[i] = variables[i];
+ }
+
+ Weight = weight;
+ }
+
+ #endregion
+ }
+}
diff --git a/BRIDGES/Solvers/GuidedProjection/Energy.cs b/BRIDGES/Solvers/GuidedProjection/Energy.cs
index 71c06d0..9af1eb8 100644
--- a/BRIDGES/Solvers/GuidedProjection/Energy.cs
+++ b/BRIDGES/Solvers/GuidedProjection/Energy.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
-using BRIDGES.Solvers.GuidedProjection.Interfaces;
+using BRIDGES.Solvers.GuidedProjection.Abstracts;
namespace BRIDGES.Solvers.GuidedProjection
@@ -9,27 +9,32 @@ namespace BRIDGES.Solvers.GuidedProjection
///
/// Class defining an energy for the .
///
- public class Energy
+ public sealed class Energy
{
#region Fields
///
- /// Energy type defining the reduced vector and the scalar value .
+ /// Variables composing the local vector localX on which the is defined.
///
- internal protected IEnergyType energyType;
+ private readonly Variable[] _variables;
- ///
- /// Variables composing the local vector xReduced on which the is defined.
- ///
- /// The first component corresponds to the variable set and the second to the index of the variable in the set.
- internal protected List<(VariableSet Set, int Index)> variables;
-
#endregion
#region Properties
///
- /// Gets or sets the weight of the energy.
+ /// Gets the energy type defining the local vector and the scalar value .
+ ///
+ public EnergyType Type { get; private set; }
+
+ ///
+ /// Gets the variables composing the local vector localX.
+ ///
+ public IReadOnlyList Variables => _variables;
+
+
+ ///
+ /// Gets or sets the weight of this energy.
///
public double Weight { get; internal set; }
@@ -40,16 +45,19 @@ public class Energy
///
/// Initialises a new instance of the class.
///
- /// Energy type defining the energy locally.
- /// Variables composing the reduced vector xReduced.
+ /// Energy type defining the local quantities of the energy.
+ /// Variables composing the local vector localX.
/// Weight of the energy.
- internal Energy(IEnergyType energyType, List<(VariableSet, int)> variablesKi, double weight)
+ public Energy(EnergyType energyType, IReadOnlyList variablesKi, double weight)
{
- // Initialise Fields
- this.energyType = energyType;
- this.variables = variablesKi;
+ this.Type = energyType;
+
+ this._variables = new Variable[variablesKi.Count];
+ for (int i = 0; i < variablesKi.Count; i++)
+ {
+ _variables[i] = variablesKi[i];
+ }
- // Initialise Properties
Weight = weight;
}
diff --git a/BRIDGES/Solvers/GuidedProjection/EnergyTypes/SegmentOrthogonality.cs b/BRIDGES/Solvers/GuidedProjection/EnergyTypes/SegmentOrthogonality.cs
index afe0818..56cc174 100644
--- a/BRIDGES/Solvers/GuidedProjection/EnergyTypes/SegmentOrthogonality.cs
+++ b/BRIDGES/Solvers/GuidedProjection/EnergyTypes/SegmentOrthogonality.cs
@@ -2,50 +2,68 @@
using System.Collections.Generic;
using BRIDGES.LinearAlgebra.Vectors;
-using BRIDGES.Solvers.GuidedProjection.Interfaces;
+using BRIDGES.Solvers.GuidedProjection.Abstracts;
namespace BRIDGES.Solvers.GuidedProjection.EnergyTypes
{
///
- /// Energy enforcing a segment defined from two point variables, pi and pj, to be orthogonal to a constant direction v.
+ /// Energy enforcing a segment to be orthogonal to a fixed direction V. The list of variables of this energy consists in:
+ ///
+ /// -
+ /// Ps
+ /// Variable representing the start point of the segment.
+ ///
+ /// -
+ /// Pe
+ /// Variable representing the end point of the segment.
+ ///
+ ///
///
- /// The vector xReduced = [pi, pj].
- public class SegmentOrthogonality : IEnergyType
+ public class SegmentOrthogonality : EnergyType
{
- #region Properties
-
- ///
- public SparseVector LocalKi { get; }
-
- ///
- public double Si { get; }
-
- #endregion
-
#region Constructors
///
/// Initialises a new instance of the class.
///
- /// Coordinates of the target direction vector.
- public SegmentOrthogonality(double[] coordinates)
+ /// Coordinates of the direction vector to which the segment must be orthogonal.
+ public SegmentOrthogonality(double[] direction)
{
- /******************** Define LocalKi ********************/
+ // ----- Unitise the direction ----- //
+
+ bool isZero = true;
+ double length = 0d;
+ for (int i = 0; i < direction.Length; i++)
+ {
+ if (isZero & Settings.AbsolutePrecision < Math.Abs(direction[i])) { isZero = false; }
+
+ length += direction[i] * direction[i];
+ }
+ length = Math.Sqrt(length);
+
+ if (isZero) { throw new DivideByZeroException("The length of the target direction must be different from zero."); }
+
+ for (int i = 0; i < direction.Length; i++)
+ {
+ direction[i] = direction[i] / length;
+ }
+
+ // ----- Define LocalKi ----- //
- Dictionary components = new Dictionary((2 * coordinates.Length));
- for (int i = 0; i < coordinates.Length; i++)
+ Dictionary components = new Dictionary((2 * direction.Length));
+ for (int i = 0; i < direction.Length; i++)
{
- components.Add(i, -coordinates[i]);
- components.Add(coordinates.Length + i, coordinates[i]);
+ components.Add(i, -direction[i]);
+ components.Add(direction.Length + i, direction[i]);
}
- LocalKi = new SparseVector(2 * coordinates.Length, ref components);
+ LocalKi = new SparseVector(2 * direction.Length, ref components);
- /******************** Define Si ********************/
+ // ----- Define Si ----- //
- Si = 0.0;
+ Si = 0d;
}
#endregion
diff --git a/BRIDGES/Solvers/GuidedProjection/EnergyTypes/SegmentParallelity.cs b/BRIDGES/Solvers/GuidedProjection/EnergyTypes/SegmentParallelity.cs
index 9943a98..c6d1169 100644
--- a/BRIDGES/Solvers/GuidedProjection/EnergyTypes/SegmentParallelity.cs
+++ b/BRIDGES/Solvers/GuidedProjection/EnergyTypes/SegmentParallelity.cs
@@ -2,69 +2,74 @@
using System.Collections.Generic;
using BRIDGES.LinearAlgebra.Vectors;
-using BRIDGES.Solvers.GuidedProjection.Interfaces;
+using BRIDGES.Solvers.GuidedProjection.Abstracts;
namespace BRIDGES.Solvers.GuidedProjection.EnergyTypes
{
///
- /// Energy enforcing a segment defined from two point variables, pi and pj, to be parallel to a constant direction v.
+ /// Energy enforcing a segment to be parallel to a fixed direction V. The list of variables of this energy consists in:
+ ///
+ /// -
+ /// Ps
+ /// Variable representing the start point of the segment.
+ ///
+ /// -
+ /// Pe
+ /// Variable representing the end point of the segment.
+ ///
+ /// -
+ /// L
+ /// Variable representing the length of the segment.
+ ///
+ ///
///
- ///
- /// A scalar variable l identified as the segment length must be defined.
- /// The vector xReduced = [pi, pj, l].
- ///
- public class SegmentParallelity : IEnergyType
+ /// The definition of a variable representing the length between to other variables must be accompanied by the use of the constraint.
+ public class SegmentParallelity : EnergyType
{
- #region Properties
-
- ///
- public SparseVector LocalKi { get; }
-
- ///
- public double Si { get; }
-
- #endregion
-
#region Constructors
///
- /// Initialises a new instance of the class by defining the coordinates of the target direction vector.
+ /// Initialises a new instance of the class.
///
- /// Coordinates of the target direction vector.
- public SegmentParallelity(double[] coordinates)
+ /// Coordinates of the direction vector to which the segment must be parallel.
+ public SegmentParallelity(double[] direction)
{
- // Unitise the direction vector
- double length = 0.0;
- for (int i = 0; i < coordinates.Length; i++)
+ // ----- Unitise the direction ----- //
+
+ bool isZero = true;
+ double length = 0d;
+ for (int i = 0; i < direction.Length; i++)
{
- length += coordinates[i] * coordinates[i];
+ if (isZero & Settings.AbsolutePrecision < Math.Abs(direction[i])) { isZero = false; }
+
+ length += direction[i] * direction[i];
}
length = Math.Sqrt(length);
- if (length == 0.0)
- {
- throw new DivideByZeroException("The length of the target direction vector must be different than zero.");
- }
+ if (isZero) { throw new DivideByZeroException("The length of the target direction must be different from zero."); }
- for (int i = 0; i < coordinates.Length; i++)
+ for (int i = 0; i < direction.Length; i++)
{
- coordinates[i] = coordinates[i] / length;
+ direction[i] = direction[i] / length;
}
- /******************** Define LocalKi ********************/
- Dictionary component = new Dictionary((2 * coordinates.Length) + 1);
- for (int i = 0; i < coordinates.Length; i++)
+ // ----- Define LocalKi ----- //
+
+ Dictionary component = new Dictionary((2 * direction.Length) + 1);
+ for (int i = 0; i < direction.Length; i++)
{
- component.Add(i, -coordinates[i]);
- component.Add(coordinates.Length + i, coordinates[i]);
+ component.Add(i, -direction[i]);
+ component.Add(direction.Length + i, direction[i]);
}
- component.Add(2 * coordinates.Length, -1);
+ component.Add(2 * direction.Length, -1);
+
+ LocalKi = new SparseVector((2 * direction.Length) + 1, ref component);
+
- LocalKi = new SparseVector((2 * coordinates.Length) + 1, ref component);
+ // ----- Define Si ----- //
- /******************** Define Si ********************/
Si = 0.0;
}
diff --git a/BRIDGES/Solvers/GuidedProjection/GuidedProjectionAlgorithm.cs b/BRIDGES/Solvers/GuidedProjection/GuidedProjectionAlgorithm.cs
index ca8bb11..9231bc3 100644
--- a/BRIDGES/Solvers/GuidedProjection/GuidedProjectionAlgorithm.cs
+++ b/BRIDGES/Solvers/GuidedProjection/GuidedProjectionAlgorithm.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Threading.Tasks;
using System.Collections.Generic;
@@ -7,8 +7,8 @@
using BRIDGES.LinearAlgebra.Matrices.Sparse;
using BRIDGES.LinearAlgebra.Matrices.Storage;
-using BRIDGES.Solvers.GuidedProjection.Interfaces;
-using System.Drawing;
+using BRIDGES.Solvers.GuidedProjection.Abstracts;
+
namespace BRIDGES.Solvers.GuidedProjection
{
@@ -20,15 +20,15 @@ public sealed class GuidedProjectionAlgorithm
{
#region Events
- /******************** For Weigths ********************/
+ // ---------- For Weigths ---------- //
///
- /// Event raised whenever and weights needs to be updated.
+ /// Event raised whenever and weights needs to be updated.
///
private event Action WeigthUpdate;
///
- /// Raises the event which updates the and the weights.
+ /// Raises the event which updates the and the weights.
///
/// Index of the current iteration.
private void OnWeigthUpdate(int iteration)
@@ -37,20 +37,19 @@ private void OnWeigthUpdate(int iteration)
}
- /******************** For Quadratic Constraints ********************/
+ // ---------- For Quadratic Constraints ---------- //
///
- /// Event raised whenever the members of needs to be updated.
+ /// Event raised whenever the members of needs to be updated.
///
- private event Action ConstraintUpdate;
+ private event Action LinearisedConstraintUpdate;
///
- /// Raises the event which updates the members of .
+ /// Raises the event which updates the members of .
///
- /// Global vector X at the current iteration.
- private void OnConstraintUpdate(in DenseVector x)
+ private void OnLinearisedConstraintUpdate()
{
- ConstraintUpdate?.Invoke(x);
+ LinearisedConstraintUpdate?.Invoke();
}
#endregion
@@ -58,25 +57,32 @@ private void OnConstraintUpdate(in DenseVector x)
#region Fields
///
- /// List of the variable sets for the .
+ /// Collection of variables of this .
///
- private List _variableSets;
+ /// The use of the collection allows for efficient search, but does not provide indexing.
+ private readonly HashSet _variables;
///
- /// List of the energies for the .
+ /// List of energies of this .
///
- private List _energies;
+ /// The use of the collection allows for efficient search, but does not provide indexing.
+ private readonly HashSet _energies;
///
- /// List of the constraints for the .
+ /// List of constraints of this .
+ /// The use of the collection allows for efficient search, but does not provide indexing.
///
- private List _constraints;
+ private readonly HashSet _constraints;
+
///
- /// Vector containing the variables of the .
+ /// Vector containing the variables of this .
///
private DenseVector _x;
+
+ // ---------- Utilities ---------- //
+
///
/// Identity matrix multiplied by Epsilon*Epsilon.
///
@@ -87,12 +93,21 @@ private void OnConstraintUpdate(in DenseVector x)
#region Properties
///
- /// Gets the vector containing all the components of the .
+ /// Gets the number of components in the global vector X of this .
+ ///
+ public int ComponentCount { get; private set; } = 0;
+
+ ///
+ /// Gets the number of energies of this .
///
- public Vector X { get { return _x; } }
+ public int EnergyCount => _energies.Count;
+ ///
+ /// Gets the number of constraints of this .
+ ///
+ public int ConstraintCount => _constraints.Count;
- /**************************************** Settings ****************************************/
+ // ---------- Settings ---------- //
///
/// Gets or sets the maximum number of iteration after which the solver is stopped.
@@ -100,40 +115,38 @@ private void OnConstraintUpdate(in DenseVector x)
public int MaxIteration { get; set; }
///
- /// Gets the zero-based index of the current iteration.
+ /// Gets index of the current iteration.
///
- public int IterationIndex { get; internal set; }
+ /// Zero means that no iteration was runned.
+ public int Iteration { get; internal set; }
- /**************************************** For Solving ****************************************/
+ // ---------- For Solving ---------- //
///
/// Gets or sets the weight of the distance to the previous iteration.
///
- double Epsilon { get; set; }
+ public double Epsilon { get; private set; }
#endregion
#region Constructors
///
- /// Initializes a new instance of the class.
+ /// Initialises a new instance of the class.
///
/// The weights of the distance to the previous iteration.
/// The iteration index after which the solver is stopped.
public GuidedProjectionAlgorithm(double epsilon, int maxIteration)
{
// Instanciate Fields
- _variableSets = new List();
-
- _energies = new List();
-
- _constraints = new List();
-
+ _variables = new HashSet();
+ _energies = new HashSet();
+ _constraints = new HashSet();
// Initialize Properties
MaxIteration = maxIteration;
- IterationIndex = 0;
+ Iteration = 0;
Epsilon = epsilon;
}
@@ -142,189 +155,196 @@ public GuidedProjectionAlgorithm(double epsilon, int maxIteration)
#region Methods
- /******************** For Variables ********************/
+ // ---------- For Variables ---------- //
///
- /// Creates a new and adds it after the other ones.
+ /// Creates a variable from its components and adds it to this model.
///
- /// The dimension of the variables contained in set.
- /// The newly created .
- public VariableSet AddVariableSet(int variableDimension)
+ /// Values of the variable's components.
+ /// The newly added .
+ public Variable AddVariable(params double[] components)
{
- int setIndex = _variableSets.Count;
+ Variable variable = new Variable(components);
- int firstRank;
- if (setIndex == 0) { firstRank = 0; }
- else
- {
- VariableSet previousSet = _variableSets[setIndex - 1];
- firstRank = previousSet.FirstRank + (previousSet.VariableCount * previousSet.VariableDimension);
- }
+ _variables.Add(variable);
+ ComponentCount += variable.Dimension;
- VariableSet newSet = new VariableSet(setIndex, firstRank, variableDimension);
- _variableSets.Add(newSet);
- return newSet;
+ return variable;
}
+
///
- /// Creates a new and adds it after the other ones.
+ /// Attempts to add the specified variable to this model.
///
- /// The dimension of the variables contained in set.
- /// The indicative number of variables that the new set can initially store.
- /// The newly created .
- public VariableSet AddVariableSet(int variableDimension, int setCapacity)
+ /// Variable to add.
+ /// if the variable was added, if the variable already exists in the model.
+ public bool TryAddVariable(Variable variable)
{
- int setIndex = _variableSets.Count;
-
- int firstRank;
- if (setIndex == 0) { firstRank = 0; }
+ if(_variables.Contains(variable)) // Complexity : O(1)
+ {
+ return false;
+ }
else
{
- VariableSet previousSet = _variableSets[setIndex - 1];
- firstRank = previousSet.FirstRank + (previousSet.VariableCount * previousSet.VariableDimension);
- }
+ _variables.Add(variable);
+ ComponentCount += variable.Dimension;
- VariableSet newSet = new VariableSet(setIndex, firstRank, variableDimension, setCapacity);
- _variableSets.Add(newSet);
- return newSet;
+ return true;
+ }
}
- /******************** For Energies ********************/
+ // ---------- For Energies ---------- //
///
- /// Creates a new with a constant weight and adds it to the list.
+ /// Creates a new with a constant weight and adds it to this model.
///
- /// Energy type defining the energy locally.
- /// Variables composing the local vector xReduced.
- /// Weight for the energy.
- /// The new energy.
- public Energy AddEnergy(IEnergyType energyType, List<(VariableSet, int)> variables, double weight = 1.0)
+ /// Energy type defining the local quantities of the energy.
+ ///
+ /// Variables composing the local vector localX.
+ /// See the class description to learn about the expected variables. The order of the variables matters.
+ ///
+ /// Weight of the energy.
+ public void AddEnergy(EnergyType energyType, IReadOnlyList variables, double weight = 1.0)
{
Energy energy = new Energy(energyType, variables, weight);
_energies.Add(energy);
-
- return energy;
}
///
- /// Creates a new with a varying weight and adds it to the list.
+ /// Creates a new with a varying weight and adds it to this model.
///
/// Energy type defining the energy locally.
- /// Variables composing the local vector xReduced.
+ ///
+ /// Variables composing the local vector localX.
+ /// See the class description to learn about the expected variables. The order of the variables matters.
+ ///
/// Function computing the weight from the iteration index.
- ///
- public Energy AddEnergy(IEnergyType energyType, List<(VariableSet, int)> variables, Func weightFunction)
+ public void AddEnergy(EnergyType energyType, IReadOnlyList variables, Func weightFunction)
{
Energy energy = new Energy(energyType, variables, 0.0);
_energies.Add(energy);
void energyWeightUpdater(int iteration) => energy.Weight = weightFunction(iteration);
WeigthUpdate += energyWeightUpdater;
-
- return energy;
}
- /******************** For Quadratic Constraints ********************/
-
///
- /// Creates a new with a constant weight and adds it to the list.
+ /// Attempts to add the specified energy to this model.
///
- /// Quadratic constraint type defining the constraint locally.
- /// Variables composing the local vector xReduced.
- /// Weight for the constraint.
- /// The new constraint.
- public QuadraticConstraint AddConstraint(IQuadraticConstraintType constraintType, List<(VariableSet, int)> variables, double weight = 1.0)
- {
- QuadraticConstraint constraint = new QuadraticConstraint(constraintType, variables, weight);
- _constraints.Add(constraint);
-
- return constraint;
- }
-
- ///
- /// Creates a new with a varying weight and adds it to the list.
- ///
- /// Quadratic constraint type defining the constraint locally.
- /// Variables composing the local vector xReduced.
- /// Function computing the weight from the iteration index.
- /// The new constraint.
- public QuadraticConstraint AddConstraint(IQuadraticConstraintType constraintType, List<(VariableSet, int)> variables, Func weightFunction)
+ /// Energy to add.
+ /// if the energy was added, if the energy already exists in the model.
+ public bool TryAddEnergy(Energy energy)
{
- QuadraticConstraint constraint = new QuadraticConstraint(constraintType, variables, 0.0);
- _constraints.Add(constraint);
-
- void constraintWeightUpdater(int iteration) => constraint.Weight = weightFunction(iteration);
- WeigthUpdate += constraintWeightUpdater;
+ if (_energies.Contains(energy)) // Complexity : O(1)
+ {
+ return false;
+ }
+ else
+ {
+ _energies.Add(energy);
- return constraint;
+ return true;
+ }
}
-
- /******************** For Linearised Constraints ********************/
+ // ---------- For Quadratic Constraints ---------- //
///
- /// Creates a new with a constant weight and adds it to the list.
+ /// Creates a new with a constant weight and adds it to this model.
///
- /// Quadratic constraint type defining the constraint locally.
- /// Variables composing the local vector xReduced.
- /// Weight for the constraint.
- /// The new constraint.
- public LinearisedConstraint AddConstraint(ILinearisedConstraintType constraintType, List<(VariableSet, int)> variables, double weight = 1.0)
+ /// Constraint type defining the constraint locally.
+ ///
+ /// Variables composing the local vector localX.
+ /// See the class description to learn about the expected variables. The order of the variables matters.
+ ///
+ /// Weight for the constraint.
+ public void AddConstraint(ConstraintType constraintType, IReadOnlyList variables, double weight = 1.0)
{
- LinearisedConstraint constraint = new LinearisedConstraint(constraintType, variables, weight);
+ Constraint constraint = new Constraint(constraintType, variables, weight);
_constraints.Add(constraint);
- return constraint;
+ if (constraintType is LinearisedConstraintType linearisedType)
+ {
+ LinearisedConstraintUpdate += () => linearisedType.UpdateLocal(variables); ;
+ }
}
///
- /// Creates a new with a varying weight and adds it to the list.
+ /// Creates a new with a varying weight and adds it to this model.
///
/// Quadratic constraint type defining the constraint locally.
- /// Variables composing the local vector xReduced.
+ ///
+ /// Variables composing the local vector localX.
+ /// See the class description to learn about the expected variables. The order of the variables matters.
+ ///
/// Function computing the weight from the iteration index.
- /// The new constraint.
- public LinearisedConstraint AddConstraint(ILinearisedConstraintType constraintType, List<(VariableSet, int)> variables, Func weightFunction)
+ public void AddConstraint(ConstraintType constraintType, IReadOnlyList variables, Func weightFunction)
{
- LinearisedConstraint constraint = new LinearisedConstraint(constraintType, variables, 0.0);
+ Constraint constraint = new Constraint(constraintType, variables, 0.0);
_constraints.Add(constraint);
void constraintWeightUpdater(int iteration) => constraint.Weight = weightFunction(iteration);
WeigthUpdate += constraintWeightUpdater;
- return constraint;
+ if (constraintType is LinearisedConstraintType linearisedType)
+ {
+ LinearisedConstraintUpdate += () => linearisedType.UpdateLocal(variables); ;
+ }
}
- /**************************************** For Solving ****************************************/
+ ///
+ /// Attempts to add the specified constraint to this model.
+ ///
+ /// Constraint to add.
+ /// if the constraint was added, if the constraint already exists in the model.
+ public bool TryAddConstraint(Constraint constraint)
+ {
+ if (_constraints.Contains(constraint)) // Complexity : O(1)
+ {
+ return false;
+ }
+ else
+ {
+ _constraints.Add(constraint);
+
+ return true;
+ }
+ }
+
+ // ---------- For Solving ---------- //
///
- /// Initialise the solver for the .
+ /// Initialises the members of this .
///
public void InitialiseX()
{
- /******************** Create global X (Variable) ********************/
+ // ----- Global vector X ----- //
+
+ double[] array = new double[ComponentCount]; // ComponentCount is updated
- // Get the size X
- VariableSet lastVariableSet = _variableSets[_variableSets.Count - 1];
- int sizeX = lastVariableSet.FirstRank + (lastVariableSet.VariableCount * lastVariableSet.VariableDimension);
+ int i_Comp = 0;
- // Create and fill X
- _x = new DenseVector(sizeX);
- for (int i_VariableSet = 0; i_VariableSet < _variableSets.Count; i_VariableSet++)
+ foreach (Variable variable in _variables)
{
- VariableSet variableSet = _variableSets[i_VariableSet];
- int componentCount = variableSet.VariableCount * variableSet.VariableDimension;
- for (int i_Component = 0; i_Component < componentCount; i_Component++)
+ // Set the components in the global vector X
+ for (int i_VarComp = 0; i_VarComp < variable.Dimension; i_VarComp++)
{
- _x[variableSet.FirstRank + i_Component] = variableSet.GetComponent(i_Component);
+ array[i_Comp + i_VarComp] = variable[i_VarComp];
}
+
+ // Change the reference in the variable to point toward a segment of the global vector X
+ variable.ChangeReference(array, i_Comp);
+
+
+ i_Comp += variable.Dimension;
}
+ _x = new DenseVector(ref array);
- /******************** Create Utilities ********************/
+ // ----- Utilities ----- //
_epsEpsIdentity = CompressedColumn.Multiply(Epsilon * Epsilon, CompressedColumn.Identity(_x.Size));
}
@@ -335,41 +355,34 @@ public void InitialiseX()
/// Evaluates whether the iteration should use asynchronous programming or not.
public void RunIteration(bool useAsync)
{
- /********** Iteration Updates **********/
+ // ----- Iteration Updates ----- //
- OnConstraintUpdate(_x);
+ OnLinearisedConstraintUpdate();
- OnWeigthUpdate(IterationIndex);
+ OnWeigthUpdate(Iteration);
- /********** Formulate and Solve the System **********/
+ // ----- Formulate and Solve the System ----- //
+ DenseVector x;
if (useAsync)
{
var task = FormAndSolveSystem_Async();
Task.WaitAll(task);
- _x = task.Result;
+ x = task.Result;
}
else
{
- _x = FormAndSolveSystem();
+ x = FormAndSolveSystem();
}
- /********** Update Variables **********/
+ // ----- Update Variables ----- //
- // Fill the VariableSet with the updated values
- for (int i_VariableSet = 0; i_VariableSet < _variableSets.Count; i_VariableSet++)
- {
- VariableSet variableSet = _variableSets[i_VariableSet];
- int componentCount = variableSet.VariableCount * variableSet.VariableDimension;
- for (int i_Component = 0; i_Component < componentCount; i_Component++)
- {
- variableSet.SetComponent(i_Component, _x[variableSet.FirstRank + i_Component]);
- }
- }
+ // Fill the _x with the actualised values
+ for (int i = 0; i < x.Size; i++) { _x[i] = x[i]; }
}
#endregion
@@ -377,9 +390,9 @@ public void RunIteration(bool useAsync)
#region Other Methods
///
- /// Compute the members of the system and solves it using Cholesky factorisation.
+ /// Computes the members of the system and solve it using Cholesky factorisation.
///
- /// The solution of the sytem.
+ /// The solution of the system.
private DenseVector FormAndSolveSystem()
{
/******************** Iterate on the quadratic constraints to create H and r ********************/
@@ -389,7 +402,7 @@ private DenseVector FormAndSolveSystem()
/******************** Iterate on the energies to create K and s ********************/
- FromEnergyMembers(out CompressedColumn K, out SparseVector s);
+ FormEnergyMembers(out CompressedColumn K, out SparseVector s);
/******************** Solve the minimisation problem ********************/
@@ -401,7 +414,7 @@ private DenseVector FormAndSolveSystem()
{
CompressedColumn HtH = CompressedColumn.TransposeMultiplySelf(H);
CompressedColumn KtK = CompressedColumn.TransposeMultiplySelf(K);
-
+
LHS = CompressedColumn.Add(HtH, KtK);
RHS = DenseVector.Add(CompressedColumn.TransposeMultiply(H, r), CompressedColumn.TransposeMultiply(K, s));
}
@@ -429,9 +442,9 @@ private DenseVector FormAndSolveSystem()
}
///
- /// Compute the members of the system and solves it using Cholesky factorisation.
+ /// Computes the members of the system and solve it using Cholesky factorisation.
///
- /// The solution of the sytem.
+ /// The solution of the system.
private async Task FormAndSolveSystem_Async()
{
CompressedColumn LHS; // Left hand side of the equation
@@ -507,10 +520,10 @@ private async Task FormAndSolveSystem_Async()
#region Helper - Synchronous
///
- /// Forms the system members derived from the constraints.
+ /// Forms the global system members derived from the constraints.
///
- /// The matrix H.
- /// The vector r.
+ /// The global matrix H.
+ /// The global vector r.
private void FormConstraintMembers(out CompressedColumn H, out DenseVector r)
{
DictionaryOfKeys dok_H = new DictionaryOfKeys(10 * _constraints.Count /* Random */);
@@ -518,67 +531,64 @@ private void FormConstraintMembers(out CompressedColumn H, out DenseVector r)
int constraintCount = 0;
- for (int i_Cstr = 0; i_Cstr < _constraints.Count; i_Cstr++)
+ foreach (Constraint cstr in _constraints)
{
- QuadraticConstraint cstr = _constraints[i_Cstr];
-
// Verifications
if (cstr.Weight == 0d) { continue; }
- List<(VariableSet Set, int Index)> variables = cstr.variables;
- IQuadraticConstraintType constraintType = cstr.constraintType;
+ IReadOnlyList variables = cstr.Variables;
+ ConstraintType constraintType = cstr.Type;
- int sizeReduced = constraintType.LocalHi.ColumnCount;
+ int localSize = constraintType.LocalHi.ColumnCount;
- /******************** Create the Row Indices ********************/
+ // ----- Create the Row Indices ----- //
- // Translating the local indices of the constraint defined on xReduced into global indices defined on x.
- List rowIndices = new List(sizeReduced);
+ // Translate the local indices of the constraint defined on localX into global indices defined on X.
+ List rowIndices = new List(localSize);
for (int i_Variable = 0; i_Variable < variables.Count; i_Variable++)
{
- int startIndex = variables[i_Variable].Set.FirstRank + (variables[i_Variable].Set.VariableDimension * variables[i_Variable].Index);
-
- for (int i_VarComp = 0; i_VarComp < variables[i_Variable].Set.VariableDimension; i_VarComp++)
- {
- rowIndices.Add(startIndex + i_VarComp);
+ Variable variable = variables[i_Variable];
+ int offset = variable.Offset;
+ for (int i_VarComp = 0; i_VarComp < variable.Dimension; i_VarComp++)
+ {
+ rowIndices.Add(offset + i_VarComp);
}
}
+ // ----- Create localX ----- //
- /******************** Create xReduced ********************/
-
- double[] components = new double[sizeReduced];
- for (int i_Comp = 0; i_Comp < sizeReduced; i_Comp++)
+ double[] components = new double[localSize];
+ for (int i_Comp = 0; i_Comp < localSize; i_Comp++)
{
components[i_Comp] = _x[rowIndices[i_Comp]];
}
- DenseVector xReduced = new DenseVector(components);
+ DenseVector localX = new DenseVector(components);
- /******************** Compute Temporary Values ********************/
+ // ----- Compute Temporary Values ----- //
// Compute HiX
- DenseVector tmp_Vect = SparseMatrix.Multiply(constraintType.LocalHi, xReduced);
+ DenseVector tmp_Vect = SparseMatrix.Multiply(constraintType.LocalHi, localX);
// Compute XtHiX
- double tmp_Val = DenseVector.TransposeMultiply(xReduced, tmp_Vect);
+ double tmp_Val = DenseVector.TransposeMultiply(localX, tmp_Vect);
- /******************** For r ********************/
+ // ----- For r ----- //
if (constraintType.Ci == 0.0) { list_r.Add(cstr.Weight * 0.5 * tmp_Val); }
else { list_r.Add(cstr.Weight * (0.5 * tmp_Val - constraintType.Ci)); }
- /******************** For H ********************/
+ // ----- For H ----- //
if (!(constraintType.LocalBi is null))
{
- tmp_Vect = DenseVector.Add(tmp_Vect, cstr.constraintType.LocalBi);
+ tmp_Vect = DenseVector.Add(tmp_Vect, constraintType.LocalBi);
}
- for (int i_Comp = 0; i_Comp < sizeReduced; i_Comp++)
+ for (int i_Comp = 0; i_Comp < localSize; i_Comp++)
{
if (tmp_Vect[i_Comp] == 0d) { continue; }
dok_H.Add(cstr.Weight * tmp_Vect[i_Comp], constraintCount, rowIndices[i_Comp]);
@@ -587,55 +597,54 @@ private void FormConstraintMembers(out CompressedColumn H, out DenseVector r)
constraintCount++;
}
+
H = new CompressedColumn(constraintCount, _x.Size, dok_H);
r = new DenseVector(list_r.ToArray());
}
///
- /// Forms the system members derived from the energies.
+ /// Forms the global system members derived from the energies.
///
- /// The matrix K.
- /// The vector s.
- private void FromEnergyMembers(out CompressedColumn K, out SparseVector s)
+ /// The global matrix K.
+ /// The global vector s.
+ private void FormEnergyMembers(out CompressedColumn K, out SparseVector s)
{
DictionaryOfKeys dok_K = new DictionaryOfKeys(10 * _energies.Count /* Random */);
Dictionary dict_s = new Dictionary(_energies.Count);
int energyCount = 0;
- for (int i_Energy = 0; i_Energy < _energies.Count; i_Energy++)
+ foreach (Energy energy in _energies)
{
- Energy energy = _energies[i_Energy];
-
// Verifications
if (energy.Weight == 0d) { continue; }
+ IReadOnlyList variables = energy.Variables;
+ EnergyType energyType = energy.Type;
- List<(VariableSet Set, int Index)> variables = energy.variables;
- IEnergyType energyType = energy.energyType;
-
+ int localSize = energyType.LocalKi.Size;
- /******************** Create the Row Indices ********************/
+ // ----- Create the Row Indices ----- //
- // Translating the local indices of the constraint defined on xReduced into global indices defined on x.
- List rowIndices = new List();
+ // Translating the local indices of the constraint defined on localX into global indices defined on X.
+ List rowIndices = new List(localSize);
for (int i_Variable = 0; i_Variable < variables.Count; i_Variable++)
{
- int startIndex = variables[i_Variable].Set.FirstRank + (variables[i_Variable].Set.VariableDimension * variables[i_Variable].Index);
-
- for (int i_Component = 0; i_Component < variables[i_Variable].Set.VariableDimension; i_Component++)
+ Variable variable = variables[i_Variable];
+ int offset = variable.Offset;
+ for (int i_VarComp = 0; i_VarComp < variable.Dimension; i_VarComp++)
{
- rowIndices.Add(startIndex + i_Component);
+ rowIndices.Add(offset + i_VarComp);
}
}
- /******************** For s ********************/
+ // ----- For s ----- //
if (!(energyType.Si == 0.0))
{
dict_s.Add(energyCount, energy.Weight * energyType.Si);
}
- /******************** For K ********************/
+ // ----- For K ----- //
foreach ((int rowIndex, double value) in energyType.LocalKi.NonZeros())
{
@@ -653,7 +662,7 @@ private void FromEnergyMembers(out CompressedColumn K, out SparseVector s)
#region Helpers - Asynchronous
- /********** Constraint Members **********/
+ // ---------- Constraint Members ---------- //
///
/// Forms the system members derived from the constraints.
@@ -665,63 +674,59 @@ private void FromEnergyMembers(out CompressedColumn K, out SparseVector s)
System.Collections.Concurrent.ConcurrentBag<(SortedDictionary ColumnHt, double ValueR)> bag
= new System.Collections.Concurrent.ConcurrentBag<(SortedDictionary ColumnHt, double ValueR)>();
- Parallel.For(0, _constraints.Count, (int i_Cstr) =>
+ Parallel.ForEach(_constraints, (Constraint cstr) =>
{
- /******************** Initialise Iteration ********************/
-
- QuadraticConstraint cstr = _constraints[i_Cstr];
-
// Verifications
if (cstr.Weight == 0d) { return; }
- List<(VariableSet Set, int Index)> variables = cstr.variables;
- IQuadraticConstraintType constraintType = cstr.constraintType;
+ IReadOnlyList variables = cstr.Variables;
+ ConstraintType constraintType = cstr.Type;
- int sizeReduced = constraintType.LocalHi.ColumnCount;
+ int localSize = constraintType.LocalHi.ColumnCount;
- /******************** Devise xReduced ********************/
+ // ----- Devise LocalX ----- //
- DenseVector xReduced = DeviseXReduced(sizeReduced, variables, out int[] rowIndices);
+ DenseVector localX = DeviseLocalX(localSize, variables, out int[] rowIndices);
- /******************** Compute Temporary Values ********************/
+ // ----- Compute Temporary Values ----- //
// Compute HiX
- DenseVector tmp_Vect = SparseMatrix.Multiply(constraintType.LocalHi, xReduced);
+ DenseVector tmp_Vect = SparseMatrix.Multiply(constraintType.LocalHi, localX);
// Compute XtHiX
- double tmp_Val = DenseVector.TransposeMultiply(xReduced, tmp_Vect);
+ double tmp_Val = DenseVector.TransposeMultiply(localX, tmp_Vect);
- /******************** For r *******************/
+ // ----- For r ----- //
double valueR = 0d;
if (constraintType.Ci == 0.0) { valueR = cstr.Weight * 0.5 * tmp_Val; }
else { valueR = cstr.Weight * (0.5 * tmp_Val - constraintType.Ci); }
- /******************** For Ht *******************/
+ // ----- For Ht ----- //
if (!(constraintType.LocalBi is null))
{
tmp_Vect = DenseVector.Add(tmp_Vect, constraintType.LocalBi);
}
- Dictionary components = new Dictionary(sizeReduced);
- for (int i_Comp = 0; i_Comp < sizeReduced; i_Comp++)
+ Dictionary components = new Dictionary(localSize);
+ for (int i_Comp = 0; i_Comp < localSize; i_Comp++)
{
if (tmp_Vect[i_Comp] == 0d) { continue; }
components.Add(rowIndices[i_Comp], cstr.Weight * tmp_Vect[i_Comp]);
}
SortedDictionary columnHt = new SortedDictionary(components);
- /******************** Finally *******************/
+ // ----- Finally ----- //
bag.Add((columnHt, valueR));
-
});
+
(CompressedColumn Ht, DenseVector r) = AssembleConstraintMembers(_x.Size, bag);
(CompressedColumn HtH, DenseVector Htr) = MultiplyConstraintMembers(Ht, r);
@@ -732,33 +737,33 @@ private void FromEnergyMembers(out CompressedColumn K, out SparseVector s)
///
- /// Devises the component of xReduced.
+ /// Devises the component of LocalX.
///
- /// Size of xReduced.
- /// Variables contained in xReduced.
- /// The row indices of the components composing xReduced.
- /// The dense vector xReduced.
- private DenseVector DeviseXReduced(int size, List<(VariableSet Set, int Index)> variables, out int[] rowIndices)
+ /// Size of LocalX.
+ /// Variables contained in LocalX.
+ /// The row indices of the components composing LocalX.
+ /// The dense vector LocalX.
+ private DenseVector DeviseLocalX(int size, IReadOnlyList variables, out int[] rowIndices)
{
- /******************** Create the Row Indices ********************/
+ // ----- Create the Row Indices ----- //
- // Translating the local indices of the constraint defined on xReduced into global indices defined on x.
+ // Translating the local indices of the constraint defined on LocalX into global indices defined on X.
rowIndices = new int[size];
int counter = 0;
for (int i_Variable = 0; i_Variable < variables.Count; i_Variable++)
{
- int startIndex = variables[i_Variable].Set.FirstRank + (variables[i_Variable].Set.VariableDimension * variables[i_Variable].Index);
-
- for (int i_VarComp = 0; i_VarComp < variables[i_Variable].Set.VariableDimension; i_VarComp++)
+ Variable variable = variables[i_Variable];
+ int offset = variable.Offset;
+ for (int i_VarComp = 0; i_VarComp < variable.Dimension; i_VarComp++)
{
- rowIndices[counter] = startIndex + i_VarComp;
+ rowIndices[counter] = offset + i_VarComp;
counter++;
}
}
- /******************** Create xReduced ********************/
+ // ----- Create LocalX ----- //
double[] components = new double[size];
for (int i_Comp = 0; i_Comp < size; i_Comp++)
@@ -771,7 +776,7 @@ private DenseVector DeviseXReduced(int size, List<(VariableSet Set, int Index)>
///
- /// Assemble the data to create the tranposed matrix Ht and the vector r.
+ /// Assembles the data to create the tranposed matrix Ht and the vector r.
///
/// Size of the global vector x.
/// Collection containing the components of the constraint members.
@@ -832,7 +837,7 @@ private DenseVector DeviseXReduced(int size, List<(VariableSet Set, int Index)>
}
- /********** Energy Members **********/
+ // ---------- Energy Members ---------- //
///
/// Forms the system members derived from the energies.
@@ -844,33 +849,31 @@ private DenseVector DeviseXReduced(int size, List<(VariableSet Set, int Index)>
System.Collections.Concurrent.ConcurrentBag<(SortedDictionary ColumnKt, double ValueS)> bag
= new System.Collections.Concurrent.ConcurrentBag<(SortedDictionary ColumnKt, double ValueS)>();
- Parallel.For(0, _energies.Count, (int i_Energy) =>
+ Parallel.ForEach(_energies, (Energy energy) =>
{
- Energy energy = _energies[i_Energy];
-
// Verifications
if (energy.Weight == 0d) { return; }
- List<(VariableSet Set, int Index)> variables = energy.variables;
- IEnergyType energyType = energy.energyType;
+ IReadOnlyList variables = energy.Variables;
+ EnergyType energyType = energy.Type;
- int sizeReduced = energyType.LocalKi.Size;
+ int localSize = energyType.LocalKi.Size;
- /******************** Create the Row Indices ********************/
+ // ----- Create the Row Indices ----- //
- // Translating the local indices of the constraint defined on xReduced into global indices defined on x.
+ // Translating the local indices of the constraint defined on LocalX into global indices defined on x.
List rowIndices = new List();
for (int i_Variable = 0; i_Variable < variables.Count; i_Variable++)
{
- int startIndex = variables[i_Variable].Set.FirstRank + (variables[i_Variable].Set.VariableDimension * variables[i_Variable].Index);
-
- for (int i_Component = 0; i_Component < variables[i_Variable].Set.VariableDimension; i_Component++)
+ Variable variable = variables[i_Variable];
+ int offset = variable.Offset;
+ for (int i_VarComp = 0; i_VarComp < variable.Dimension; i_VarComp++)
{
- rowIndices.Add(startIndex + i_Component);
+ rowIndices.Add(offset + i_VarComp);
}
}
- /******************** For s ********************/
+ // ----- For s ----- //
double valueS = 0.0;
if (!(energyType.Si == 0.0))
@@ -878,9 +881,9 @@ private DenseVector DeviseXReduced(int size, List<(VariableSet Set, int Index)>
valueS = energy.Weight * energyType.Si;
}
- /******************** For Kt ********************/
+ // ----- For Kt ----- //
- Dictionary components = new Dictionary(sizeReduced);
+ Dictionary components = new Dictionary(localSize);
foreach ((int rowIndex, double value) in energyType.LocalKi.NonZeros())
{
components.Add(rowIndices[rowIndex], energy.Weight * value);
@@ -888,14 +891,14 @@ private DenseVector DeviseXReduced(int size, List<(VariableSet Set, int Index)>
SortedDictionary ColumnKt = new SortedDictionary(components);
- /******************** Finally *******************/
+ // ----- Finally ----- //
bag.Add((ColumnKt, valueS));
-
});
- (CompressedColumn Kt, SparseVector s) = AssembleEnergyMembers(_x.Size, bag);
+ (CompressedColumn Kt, SparseVector s) = AssembleEnergyMembers(_x.Size, bag);
+
(CompressedColumn KtK, SparseVector Kts) = MultiplyEnergyMembers(Kt, s);
return (KtK, Kts as Vector);
@@ -904,7 +907,7 @@ private DenseVector DeviseXReduced(int size, List<(VariableSet Set, int Index)>
///
- /// Assemble the data to create the tranposed matrix Kt and the vector s.
+ /// Assembles the data to create the tranposed matrix Kt and the vector s.
///
/// Size of the global vector x.
/// Collection containing the components of the constraint members.
diff --git a/BRIDGES/Solvers/GuidedProjection/Interfaces/IEnergyType.cs b/BRIDGES/Solvers/GuidedProjection/Interfaces/IEnergyType.cs
deleted file mode 100644
index 1a415f3..0000000
--- a/BRIDGES/Solvers/GuidedProjection/Interfaces/IEnergyType.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-
-using BRIDGES.LinearAlgebra.Vectors;
-
-
-namespace BRIDGES.Solvers.GuidedProjection.Interfaces
-{
- ///
- /// Interface defining an energy type for the .
- ///
- public interface IEnergyType
- {
- #region Properties
-
- ///
- /// Gets the local vector Ki of the energy.
- ///
- SparseVector LocalKi { get; }
-
- ///
- /// Gets the scalar value Si of the energy.
- ///
- double Si { get; }
-
- #endregion
- }
-}
diff --git a/BRIDGES/Solvers/GuidedProjection/Interfaces/ILinearisedConstraintType.cs b/BRIDGES/Solvers/GuidedProjection/Interfaces/ILinearisedConstraintType.cs
deleted file mode 100644
index b10c46c..0000000
--- a/BRIDGES/Solvers/GuidedProjection/Interfaces/ILinearisedConstraintType.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-
-namespace BRIDGES.Solvers.GuidedProjection.Interfaces
-{
- ///
- /// Interface defining a linearised constraint type for the .
- ///
- public interface ILinearisedConstraintType : IQuadraticConstraintType
- {
- #region Methods
-
- ///
- /// Updates the local members (LocalHi, LocalBi) of the linearised constraint using xReduced.
- ///
- /// Actualized components of the local vector xReduced formed from the constraint variables.
- void UpdateLocal(double[] xReduced);
-
- #endregion
- }
-}
diff --git a/BRIDGES/Solvers/GuidedProjection/LinearisedConstraint.cs b/BRIDGES/Solvers/GuidedProjection/LinearisedConstraint.cs
deleted file mode 100644
index 357804c..0000000
--- a/BRIDGES/Solvers/GuidedProjection/LinearisedConstraint.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-using BRIDGES.LinearAlgebra.Vectors;
-
-using BRIDGES.Solvers.GuidedProjection.Interfaces;
-
-
-namespace BRIDGES.Solvers.GuidedProjection
-{
- ///
- /// Class defining a linearised constraint for the .
- ///
- public sealed class LinearisedConstraint : QuadraticConstraint
- {
- #region Constructors
-
- ///
- /// Initialises a new instance of the class.
- ///
- /// Constraint type defining the constraint locally.
- /// Variables composing the reduced vector xReduced on which the local symmetric matrix Hi and the local vector Bi are defined.
- /// Weight of the constraint.
- internal LinearisedConstraint(ILinearisedConstraintType constraintType, List<(VariableSet, int)> variables, double weight)
- : base(constraintType, variables, weight)
- {
- /* Do nothing */
- }
-
- #endregion
-
- #region Other Methods
-
- ///
- /// Updates the local members (LocalHi, LocalBi) of the linearised constraint using x,
- ///
- /// Global vector x at the current iteration.
- internal void Update(DenseVector x)
- {
- double[] xReduced = GetXReduced(x);
-
- ILinearisedConstraintType linearisedConstraintType = constraintType as ILinearisedConstraintType;
- linearisedConstraintType.UpdateLocal(xReduced);
- }
-
-
- ///
- /// Retrieves the components of the local vector xReduced from its global equivalent x.
- ///
- /// The global vector x.
- /// the components of xReduced
- private double[] GetXReduced(in DenseVector x)
- {
- List result = new List();
- for (int i_LocalVariable = 0; i_LocalVariable < variables.Count; i_LocalVariable++)
- {
- VariableSet variableSet = variables[i_LocalVariable].Set;
- int variableIndex = variables[i_LocalVariable].Index;
-
- result.AddRange(variableSet.GetVariable(variableIndex));
- }
-
- return result.ToArray();
- }
-
- #endregion
- }
-}
diff --git a/BRIDGES/Solvers/GuidedProjection/QuadraticConstraint.cs b/BRIDGES/Solvers/GuidedProjection/QuadraticConstraint.cs
deleted file mode 100644
index 517277b..0000000
--- a/BRIDGES/Solvers/GuidedProjection/QuadraticConstraint.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-using BRIDGES.Solvers.GuidedProjection.Interfaces;
-
-
-namespace BRIDGES.Solvers.GuidedProjection
-{
- ///
- /// Class defining a quadratic constraint for the .
- ///
- public class QuadraticConstraint
- {
- #region Fields
-
- /// ///
- /// Constraint type defining the reduced matrix ,
- /// the reduced vector and the scalar value .
- ///
- internal protected IQuadraticConstraintType constraintType;
-
- ///
- /// Variables composing the local vector xReduced on which the is defined.
- ///
- /// The first item corresponds to the variable set and the second to the index of the variable in the set.
- internal protected List<(VariableSet Set, int Index)> variables;
-
- #endregion
-
- #region Properties
-
- ///
- /// Gets or sets the value of the weight for the constraint.
- ///
- public double Weight { get; internal set; }
-
- #endregion
-
- #region Constructors
-
- ///
- /// Initialises a new instance of the class.
- ///
- /// Constraint type defining the constraint locally.
- /// Variables composing the reduced vector xReduced on which the local symmetric matrix Hi and the local vector Bi are defined.
- /// Weight of the constraint.
- internal QuadraticConstraint(IQuadraticConstraintType constraintType, List<(VariableSet, int)> variables, double weight)
- {
- // Initialize Properties
- this.constraintType = constraintType;
- this.variables = variables;
-
- // Initialize Properties
- Weight = weight;
- }
-
- #endregion
- }
-}
diff --git a/BRIDGES/Solvers/GuidedProjection/QuadraticConstraintTypes/CoherentLength.cs b/BRIDGES/Solvers/GuidedProjection/QuadraticConstraintTypes/CoherentLength.cs
index 415e837..a1b391a 100644
--- a/BRIDGES/Solvers/GuidedProjection/QuadraticConstraintTypes/CoherentLength.cs
+++ b/BRIDGES/Solvers/GuidedProjection/QuadraticConstraintTypes/CoherentLength.cs
@@ -1,72 +1,71 @@
using System;
-using BRIDGES.LinearAlgebra.Vectors;
-using BRIDGES.LinearAlgebra.Matrices;
using BRIDGES.LinearAlgebra.Matrices.Sparse;
-using BRIDGES.Solvers.GuidedProjection.Interfaces;
+using BRIDGES.Solvers.GuidedProjection.Abstracts;
namespace BRIDGES.Solvers.GuidedProjection.QuadraticConstraintTypes
{
///
- /// Constraint enforcing a scalar variable l to match with the distance between two point variables, pi and pj.
+ /// Constraint enforcing a scalar variable to match with the distance between two variables. The list of variables of this constraint consists in:
+ ///
+ /// -
+ /// Pi
+ /// First variable with which the distance is being computed.
+ ///
+ /// -
+ /// Pj
+ /// Second variable with which the distance is being computed.
+ ///
+ /// -
+ /// L
+ /// Scalar variable to match with the distance.
+ ///
+ ///
///
- /// The vector xReduced = [pi, pj, l].
- public class CoherentLength : IQuadraticConstraintType
+ public class CoherentLength : ConstraintType
{
- #region Properties
-
- ///
- public SparseMatrix LocalHi { get; }
-
- ///
- public SparseVector LocalBi { get; }
-
- ///
- public double Ci { get; }
-
- #endregion
-
#region Constructors
///
/// Initialises a new instance of the class.
///
- /// Dimension of the space containing the points.
- public CoherentLength(int spaceDimension = 3)
+ /// Common dimension of the variables with which the distance is being computed.
+ public CoherentLength(int dimension)
{
- /******************** Define LocalHi ********************/
+ // ----- Define LocalHi ----- //
- int[] columnPointers = new int[(2 * spaceDimension) + 2];
- int[] rowIndices = new int[(4 * spaceDimension) + 1];
- double[] values = new double[(4 * spaceDimension) + 1];
+ int[] columnPointers = new int[(2 * dimension) + 2];
+ int[] rowIndices = new int[(4 * dimension) + 1];
+ double[] values = new double[(4 * dimension) + 1];
columnPointers[0] = 0;
- for (int i_C = 0; i_C < spaceDimension; i_C++)
+ for (int i_C = 0; i_C < dimension; i_C++)
{
columnPointers[i_C + 1] = 2 * (i_C + 1);
- rowIndices[(2 * i_C)] = i_C; rowIndices[(2 * i_C) + 1] = spaceDimension + i_C;
+ rowIndices[(2 * i_C)] = i_C; rowIndices[(2 * i_C) + 1] = dimension + i_C;
values[(2 * i_C)] = 2.0; values[(2 * i_C) + 1] = -2.0;
- columnPointers[spaceDimension + i_C + 1] = 2 * (spaceDimension + i_C + 1);
- rowIndices[(2 * (spaceDimension + i_C))] = i_C; rowIndices[(2 * (spaceDimension + i_C)) + 1] = spaceDimension + i_C;
- values[(2 * (spaceDimension + i_C))] = -2.0; values[(2 * (spaceDimension + i_C)) + 1] = 2.0;
+ columnPointers[dimension + i_C + 1] = 2 * (dimension + i_C + 1);
+ rowIndices[(2 * (dimension + i_C))] = i_C; rowIndices[(2 * (dimension + i_C)) + 1] = dimension + i_C;
+ values[(2 * (dimension + i_C))] = -2.0; values[(2 * (dimension + i_C)) + 1] = 2.0;
}
- columnPointers[(2 * spaceDimension) + 1] = (4 * spaceDimension) + 1;
- rowIndices[(4 * spaceDimension)] = (2 * spaceDimension);
- values[(4 * spaceDimension)] = -2.0;
+ columnPointers[(2 * dimension) + 1] = (4 * dimension) + 1;
+ rowIndices[(4 * dimension)] = (2 * dimension);
+ values[(4 * dimension)] = -2.0;
- LocalHi = new CompressedColumn((2 * spaceDimension) + 1, (2 * spaceDimension) + 1, columnPointers, rowIndices, values);
+ LocalHi = new CompressedColumn((2 * dimension) + 1, (2 * dimension) + 1, columnPointers, rowIndices, values);
- /******************** Define LocalBi ********************/
+ // ----- Define LocalBi ----- //
LocalBi = null ;
- /******************** Define Ci ********************/
- Ci = 0.0;
+ // ----- Define Ci ----- //
+
+ Ci = 0d;
}
#endregion
diff --git a/BRIDGES/Solvers/GuidedProjection/QuadraticConstraintTypes/LowerBound.cs b/BRIDGES/Solvers/GuidedProjection/QuadraticConstraintTypes/LowerBound.cs
index bc5f09f..52079ac 100644
--- a/BRIDGES/Solvers/GuidedProjection/QuadraticConstraintTypes/LowerBound.cs
+++ b/BRIDGES/Solvers/GuidedProjection/QuadraticConstraintTypes/LowerBound.cs
@@ -2,63 +2,54 @@
using System.Collections.Generic;
using BRIDGES.LinearAlgebra.Vectors;
-using BRIDGES.LinearAlgebra.Matrices;
using BRIDGES.LinearAlgebra.Matrices.Sparse;
-using BRIDGES.Solvers.GuidedProjection.Interfaces;
+using BRIDGES.Solvers.GuidedProjection.Abstracts;
namespace BRIDGES.Solvers.GuidedProjection.QuadraticConstraintTypes
{
///
- /// Constraint enforcing a value variable l to be higher than a lower bound σ using a dummy value variable λ.
+ /// Constraint enforcing a scalar variable to be larger than a fixed lower bound. The list of variables of this constraint consists in:
+ ///
+ /// -
+ /// S
+ /// Scalar variable to maintain above the fixed lower bound.
+ ///
+ /// -
+ /// X
+ /// Dummy scalar variable used for the constraint formulation.
+ ///
+ ///
///
- /// The vector xReduced = [l, λ], and Ci = σ.
- public class LowerBound : IQuadraticConstraintType
+ public class LowerBound : ConstraintType
{
- #region Properties
-
- ///
- public SparseMatrix LocalHi { get; }
-
- ///
- public SparseVector LocalBi { get; }
-
- ///
- public double Ci { get; }
-
- #endregion
-
#region Constructors
///
/// Initialises a new instance of the class.
///
- /// Value of the lower bound of the constraint.
- public LowerBound(double lowerBound)
+ /// Value of the lower bound.
+ public LowerBound(double bound)
{
- /******************** Define LocalHi ********************/
+ // ----- Define LocalHi ----- //
- int[] columnPointers = new int[3];
- int[] rowIndices = new int[1];
- double[] values = new double[1];
-
- columnPointers[0] = 0;
- columnPointers[1] = 0;
- columnPointers[2] = 1; rowIndices[0] = 1; values[0] = 2.0;
+ int[] columnPointers = new int[] { 0, 0, 1 };
+ int[] rowIndices = new int[] { 1 };
+ double[] values = new double[] { 2d };
LocalHi = new CompressedColumn(2, 2, columnPointers, rowIndices, values);
- /******************** Define LocalBi ********************/
+ // ----- Define LocalBi ----- //
- Dictionary components = new Dictionary();
- components.Add(0, -1.0);
+ Dictionary components = new Dictionary { { 0, -1.0 } };
LocalBi = new SparseVector(2, ref components);
- /******************** Define Ci ********************/
- Ci = lowerBound;
+ // ----- Define Ci ----- //
+
+ Ci = bound;
}
#endregion
diff --git a/BRIDGES/Solvers/GuidedProjection/QuadraticConstraintTypes/UpperBound.cs b/BRIDGES/Solvers/GuidedProjection/QuadraticConstraintTypes/UpperBound.cs
index 60ef475..e9b05cb 100644
--- a/BRIDGES/Solvers/GuidedProjection/QuadraticConstraintTypes/UpperBound.cs
+++ b/BRIDGES/Solvers/GuidedProjection/QuadraticConstraintTypes/UpperBound.cs
@@ -2,63 +2,54 @@
using System.Collections.Generic;
using BRIDGES.LinearAlgebra.Vectors;
-using BRIDGES.LinearAlgebra.Matrices;
using BRIDGES.LinearAlgebra.Matrices.Sparse;
-using BRIDGES.Solvers.GuidedProjection.Interfaces;
+using BRIDGES.Solvers.GuidedProjection.Abstracts;
namespace BRIDGES.Solvers.GuidedProjection.QuadraticConstraintTypes
{
///
- /// Constraint enforcing a value variable l to be lower than an upper bound σ using a dummy value variable λ.
+ /// Constraint enforcing a scalar variable to be smaller than a fixed upper bound. The list of variables of this constraint consists in:
+ ///
+ /// -
+ /// S
+ /// Scalar variable to maintain under the fixed upper bound.
+ ///
+ /// -
+ /// X
+ /// Dummy scalar variable used for the constraint formulation.
+ ///
+ ///
///
- /// The vector xReduced = [l, λ], and Ci = σ.
- public class UpperBound : IQuadraticConstraintType
+ public class UpperBound : ConstraintType
{
- #region Properties
-
- ///
- public SparseMatrix LocalHi { get; }
-
- ///
- public SparseVector LocalBi { get; }
-
- ///
- public double Ci { get; }
-
- #endregion
-
#region Constructors
///
/// Initialises a new instance of the class.
///
- /// Value of the upper bound of the constraint.
- public UpperBound(double upperBound)
+ /// Value of the upper bound.
+ public UpperBound(double bound)
{
- /******************** Define LocalHi ********************/
+ // ----- Define LocalHi ----- //
- int[] columnPointers = new int[3];
- int[] rowIndices = new int[1];
- double[] values = new double[1];
-
- columnPointers[0] = 0;
- columnPointers[1] = 0;
- columnPointers[2] = 1; rowIndices[0] = 1; values[0] = -2.0;
+ int[] columnPointers = new int[3] { 0, 0, 1 };
+ int[] rowIndices = new int[1] { 1 };
+ double[] values = new double[1] { -2d };
LocalHi = new CompressedColumn(2, 2, columnPointers, rowIndices, values);
- /******************** Define LocalBi ********************/
+ // ----- Define LocalBi ----- //
- Dictionary components = new Dictionary();
- components.Add(0, -1.0);
+ Dictionary components = new Dictionary { { 0, -1.0 } };
LocalBi = new SparseVector(2, ref components);
- /******************** Define Ci ********************/
- Ci = upperBound;
+ // ----- Define Ci ----- //
+
+ Ci = bound;
}
#endregion
diff --git a/BRIDGES/Solvers/GuidedProjection/QuadraticConstraintTypes/VectorLength.cs b/BRIDGES/Solvers/GuidedProjection/QuadraticConstraintTypes/VectorLength.cs
index f4a1504..e76ac69 100644
--- a/BRIDGES/Solvers/GuidedProjection/QuadraticConstraintTypes/VectorLength.cs
+++ b/BRIDGES/Solvers/GuidedProjection/QuadraticConstraintTypes/VectorLength.cs
@@ -1,66 +1,56 @@
using System;
-using System.Collections.Generic;
-using BRIDGES.LinearAlgebra.Matrices;
+
using BRIDGES.LinearAlgebra.Matrices.Sparse;
-using BRIDGES.LinearAlgebra.Matrices.Storage;
-using BRIDGES.LinearAlgebra.Vectors;
-using BRIDGES.Solvers.GuidedProjection.Interfaces;
+using BRIDGES.Solvers.GuidedProjection.Abstracts;
namespace BRIDGES.Solvers.GuidedProjection.QuadraticConstraintTypes
{
///
- /// Constraint enforcing a vector variable v to have a given length l (computed with euclidean norm).
+ /// Constraint enforcing a vector variable to equal a fixed target length (computed with euclidean norm). The list of variables of this constraint consists in:
+ ///
+ /// -
+ /// V
+ /// Variable representing the vector to resize.
+ ///
+ ///
///
- /// The vector xReduced = [v], and Ci = l2.
- public class VectorLength : IQuadraticConstraintType
+ public class VectorLength : ConstraintType
{
- #region Properties
-
- ///
- public SparseMatrix LocalHi { get; }
-
- ///
- public SparseVector LocalBi { get; }
-
- ///
- public double Ci { get; }
-
- #endregion
-
#region Constructors
///
/// Initialises a new instance of the class.
///
- /// Target length for the vector.
- /// Dimension of the space containing the vector.
- public VectorLength(double targetLength, int spaceDimension = 3)
+ /// Target length of the vector.
+ /// Dimension of the vector variable.
+ public VectorLength(double length, int dimension = 3)
{
- /******************** Define LocalHi ********************/
+ // ----- Define LocalHi ********************/
- int[] columnPointers = new int[spaceDimension + 1];
- int[] rowIndices = new int[spaceDimension];
- double[] values = new double[spaceDimension];
+ int[] columnPointers = new int[dimension + 1];
+ int[] rowIndices = new int[dimension];
+ double[] values = new double[dimension];
columnPointers[0] = 0;
- for (int i = 0; i < spaceDimension; i++)
+ for (int i = 0; i < dimension; i++)
{
columnPointers[i + 1] = i + 1;
rowIndices[i] = i;
values[i] = -2.0;
}
- LocalHi = new CompressedColumn(spaceDimension, spaceDimension, columnPointers, rowIndices, values);
+ LocalHi = new CompressedColumn(dimension, dimension, columnPointers, rowIndices, values);
- /******************** Define LocalBi ********************/
+ // ----- Define LocalBi ----- //
LocalBi = null;
- /******************** Define Ci ********************/
- Ci = targetLength * targetLength;
+ // ----- Define Ci ----- //
+
+ Ci = length * length;
}
#endregion
diff --git a/BRIDGES/Solvers/GuidedProjection/Variable.cs b/BRIDGES/Solvers/GuidedProjection/Variable.cs
new file mode 100644
index 0000000..2c4e74f
--- /dev/null
+++ b/BRIDGES/Solvers/GuidedProjection/Variable.cs
@@ -0,0 +1,145 @@
+using System;
+
+
+namespace BRIDGES.Solvers.GuidedProjection
+{
+ ///
+ /// Variable of the .
+ ///
+ public sealed class Variable : IEquatable
+ {
+ #region Fields
+
+ ///
+ /// Segment of the global vector X representing this variable.
+ ///
+ private ArraySegment _components;
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets the component at the specified index in this variable.
+ ///
+ /// The zero-based index of the variable's component to get.
+ /// The component at the specified index.
+ public double this[int index]
+ {
+ get
+ {
+ return index < _components.Count ? _components.Array[_components.Offset + index] :
+ throw new IndexOutOfRangeException("The index must be positive and smaller than the dimmension of the variable.");
+ }
+ }
+
+ ///
+ /// Get the number of components of this variable.
+ ///
+ public int Dimension => _components.Count;
+
+
+ ///
+ /// Gets the index of the variable's first component, relative to the start of the global vector X.
+ ///
+ internal int Offset => _components.Offset;
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Initialises a new instance of the class from its components.
+ ///
+ /// Components of the variable.
+ public Variable(params double[] components)
+ {
+ if (components is null) { throw new ArgumentNullException(nameof(components)); }
+ if (components.Length == 0) { throw new RankException("The variable must be initialised with at least one component value."); }
+
+ double[] array = (double[])components.Clone();
+
+ _components = new ArraySegment(array);
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Creates an array representation of the variable.
+ ///
+ /// The double-precision array representing the variable.
+ public double[] ToArray()
+ {
+ double[] array = new double[Dimension];
+ for (int i = 0; i < Dimension; i++)
+ {
+ array[i] = this[i];
+ }
+
+ return array;
+ }
+
+
+ ///
+ /// Creates a representation of the variable
+ ///
+ /// The representation of the variable.
+ public Span ToSpan()
+ {
+ return new Span(_components.Array, _components.Offset, _components.Count);
+ }
+
+ ///
+ /// Creates a representation of the variable
+ ///
+ /// Zero-based index of the first component to include in the .
+ /// Number of components to include in the .
+ /// The representation of the variable.
+ public Span ToSpan(int start, int count)
+ {
+ return new Span(_components.Array, _components.Offset + start, count);
+ }
+
+
+ ///
+ /// Changes the reference of this variable.
+ ///
+ /// Interfering with the variable's reference can create issues with the solving.
+ /// New array to refer to.
+ /// Index of the variable's first component in the array.
+ internal void ChangeReference(double[] array, int offset)
+ {
+ _components = new ArraySegment(array, offset, Dimension);
+ }
+
+
+ // ---------- Implement IEquatable<.> ---------- //
+
+ ///
+ /// Indicates whether this is equal to another .
+ /// A to compare with this one.
+ /// if their field are equal, otherwise.
+ public bool Equals(Variable other) => _components.Equals(other._components);
+
+ #endregion
+
+
+ #region Override : Object
+
+ ///
+ public override bool Equals(object obj)
+ {
+ return obj is Variable variable && Equals(variable);
+ }
+
+ ///
+ public override int GetHashCode()
+ {
+ return 1716805434 + _components.GetHashCode();
+ }
+
+ #endregion
+ }
+}
diff --git a/BRIDGES/Solvers/GuidedProjection/VariableSet.cs b/BRIDGES/Solvers/GuidedProjection/VariableSet.cs
deleted file mode 100644
index a1a8b3d..0000000
--- a/BRIDGES/Solvers/GuidedProjection/VariableSet.cs
+++ /dev/null
@@ -1,146 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-
-namespace BRIDGES.Solvers.GuidedProjection
-{
- ///
- /// Class defining a set of variables with the same dimension (i.e. variables with the same number of components).
- ///
- public class VariableSet
- {
- #region Fields
-
- ///
- /// List of variables of the set.
- ///
- private List _variables;
-
- #endregion
-
- #region Properties
-
- ///
- /// Gets the index of the set in the 's list of variable sets.
- ///
- public int SetIndex { get; private set; }
-
- ///
- /// Gets the common dimension of variables in the set.
- ///
- public int VariableDimension { get; private set; }
-
- ///
- /// Gets the number of variables in the set.
- ///
- public int VariableCount { get; private set; }
-
-
- ///
- /// Gets the rank of the first component of the first variable in the set.
- ///
- internal int FirstRank { get; private set; }
-
- #endregion
-
- #region Constructors
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// Index of the set in the 's list of variable sets.
- /// Rank of the first component of the first variable in the set.
- /// Dimension of the variables in the set.
- internal VariableSet(int setIndex, int firstRank, int variableDimension)
- {
- // Instanciate Fields
- _variables = new List();
-
- // Initialise Properties
- FirstRank = firstRank;
-
- SetIndex = setIndex;
- VariableCount = 0;
- VariableDimension = variableDimension;
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// Index of the set in the 's list of VariableSet.
- /// Index of the first component of the first variable in the set.
- /// Dimension of the variables contained in the set.
- /// Indicative capacity of the set.
- internal VariableSet(int setIndex, int firstRank, int variableDimension, int setCapacity)
- {
- // Instanciate Fields
- _variables = new List(variableDimension * setCapacity);
-
- // Initialise Properties
- FirstRank = firstRank;
-
- SetIndex = setIndex;
- VariableCount = 0;
- VariableDimension = variableDimension;
- }
-
- #endregion
-
- #region Methods
-
- ///
- /// Returns the component at the given index in the set.
- ///
- /// Index of the component to get.
- /// The component at the given index in the set.
- internal double GetComponent(int componentIndex)
- {
- return _variables[componentIndex];
- }
-
- ///
- /// Sets the component at the given index in the set.
- ///
- /// Index of the component to set.
- /// Value to set.
- internal void SetComponent(int componentIndex, double value)
- {
- _variables[componentIndex] = value;
- }
-
-
- ///
- /// Adds a variable to the set.
- ///
- /// Components of the variables to add.
- public void AddVariable(params double[] components)
- {
- if (components.Length != VariableDimension)
- {
- throw new ArgumentOutOfRangeException("The number of components for the new variable" +
- "does not match the expected dimension of the variables of the set.");
- }
-
- _variables.AddRange(components);
- VariableCount++;
- }
-
- ///
- /// Returns the components of the variable at the given index.
- ///
- /// Index of the variable to get.
- /// The components of the variable at the index.
- public double[] GetVariable(int variableIndex)
- {
- double[] variable = new double[VariableDimension];
- int index = variableIndex * VariableDimension;
- for (int i = 0; i < VariableDimension; i++)
- {
- variable[i] = _variables[index + i];
- }
- return variable;
- }
-
- #endregion
- }
-}