Skip to content
This repository was archived by the owner on Nov 19, 2020. It is now read-only.

Conversation

CatchemAL
Copy link
Collaborator

@CatchemAL CatchemAL commented Sep 11, 2017

Hi @cesarsouza,

I know I can merge in directly but I'd really appreciate your thoughts on 3 points.

  • Throws NonSymmetricMatrixException if relative tolerance is > 1e-6. Does that sound reasonable to you? I didn't want the requirement for the matrix to be symmetric to be too much of a burden but i can still envisage scenarios where this might throw. Any better suggestions 100% welcome. Alternatively, if it detects a non-symmetric matrix, it could always grab the non-symmetric part and continue.
  • Documentation as requested :) I have tried my best to add XML documentation but I am afraid I couldn't completely fathom out SandCastle. Please would you confirm I have done this correctly? Thank you!
  • As discussed (Very minor bug in quadratic objective function #832), I changed the default variable names to improve readability. However, thinking about it a bit more, I want to check you are happy with this change. If anyone was indexing into the IDictionary<string, int> Variables, their code would now break. It's also not consistent with the NonlinearObjectiveFunction. So I can: leave it as is; change the Nonlinear as well for consistency; revert completely; or simply change the ToString() method aesthetically but not touch the underlying variable names.

Reminder:

before: 4x0x0 +2x1x1 +3x2x2 +3x0x1 +1x0x2 +2x1x2
after : 4x₀² +2x₁² +3x₂² +3x₀x₁ +1x₀x₂ +2x₁x₂

Happy to make changes as you see fit.

Thanks!
Alex

ps - this closes #819

…of the quadratic objective function.

 - Switched the ConstantTerm to an auto-property (cleaner)
 - Moved parsing logic to its own static class, QuadraticExpressionParser.cs (cleaner). TODO recycle parsing logic in QuadraticConstraint??
 - Fixing issue where Expressions are incorrectly parsed. For instance f = xy + yx fails because duplicate terms are only counted once.
 - Speeding up gradient calculation by removing weird transpose. *** MAJOR ISSUE: calculation is STILL incorrect for non-symmetric matrices ***. Need to decide the best fix. Either 0.5(Q+Q') or, simply, Q but force Q to be symmetric.

Adding a check on whether the quadratic and linear dictionaries are null and returning an alternative string in these cases. This fixes GH-832. Not including zeros because f = 2x+0y+1z is confusingly shown as "+2x +y +1z!"
# Conflicts:
#	Sources/Accord.Math/Matrix/Matrix.Common.cs
#	Unit Tests/Accord.Tests.Math/Optimization/QuadraticObjectiveFunctionTest.cs
{ 1, 3, 1 },
{ 3, 2, 2 },
{ 1, 2, 3 },
{ 8, 3, 1 },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I am ok with the change, but why was it needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see :D I must admit I spent more than 20 mins trying to remember why this was actually changed (it wasn't really a deliberate change). Anyways, I remember now...

The ToString() method only displays the coefficients to the nearest integer (it's always been like that - not a change from me). As that test has odd numbers down the diagonal, the ToString() looked funny. I just switched it to even numbers to verify I hadn't broken it. I can revert it if you like but I presume(d) those numbers were arbitrary.

@@ -242,8 +241,8 @@ public void FunctionTest()
double e = expected();

Assert.AreEqual(e, a, 1e-10);
Assert.IsFalse(Double.IsNaN(a));
Assert.IsFalse(Double.IsNaN(e));
Assert.IsFalse(double.IsNaN(a));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, just in case you might be wondering, the checks against NaN even though we already had checked for equality were needed when the project used MSTest for unit tests. Now that we use NUnit3, they shouldn't be that much necessary (but they also don't hurt anyway).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -127,20 +145,23 @@ namespace Accord.Math.Optimization
/// double value = solver.Value;
/// double[] solutions = solver.Solution;
/// </code>
///
/// <para>
/// Sometimes it easiest to compose quadratic functions as linear
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a typo here? Sorry I am not a native English speaker, so I thought it was better to ask :-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was indeed. Thanks for spotting. I have fixed the typo and pushed. BTW - if you want a native speaker to review your arXiv article I am more than happy to. However, to be completely clear, your English seems absolutely faultless - and I make typos :) - so I'm not sure I see the need!

throw new DimensionMismatchException("quadraticTerms", "The matrix must be square.");

if (quadraticTerms.GetLength(0) != linearTerms.Length)
if (!quadraticTerms.IsSymmetric(rtol: 1e-6))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine. If for some reason it throws for a matrix that was indeed supposed to be symmetric, the user can always "force" it to be symmetric with GetSymmetric or manually.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool - my thinking was similar and I had spotted that method - would work well. Another pair of methods that would be useful would be GetSymmetricPart() and GetAntiSymmetricPart evaluating 0.5(M+M') and 0.5(M-M') respectively.

/// supports this by overloading the addition and multiplication operators.
/// </para>
///
/// <code source="Unit Tests\Accord.Tests.Math\Optimization\QuadraticObjectiveFunctionTest.cs" region="doc_example" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is perfect, thanks for following the style so closely!

@cesarsouza cesarsouza merged commit 040eb57 into accord-net:development Sep 20, 2017
@cesarsouza
Copy link
Member

Thanks a lot @AlexJCross!

@CatchemAL
Copy link
Collaborator Author

@cesarsouza as always, you're welcome. Thanks for accepting this PR!

@CatchemAL CatchemAL deleted the GH-819 branch September 20, 2017 21:31
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Quadratic Objective Function to support basic vector operations
2 participants