Skip to end of metadata
Go to start of metadata

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

Zend Framework: Zend_Math Component Proposal

Proposed Component Name Zend_Math
Developer Notes http://framework.zend.com/wiki/display/ZFDEV/Zend_Math
Proposers Walter Tamboer
Zend Liaison Dolf Schimmel (Freeaqingme)
Revision 2.0 - 02 Jun 2011: Finished the proposal code so that it can be reviewed.
1.0 - 29 May 2011: Initial Draft. (wiki revision: 7)

Table of Contents

1. Overview

Zend_Math is a component which contains math related functions and classes. The purpose of this component is to make life easier for people who are doing vector and matrix math for example.

2. References

3. Component Requirements, Constraints, and Acceptance Criteria

  • This component will support helper methods such as "clamp" and "lerp".
  • This component will support vector classes to do vector math.
  • This component will support matrix classes to do matrix math.
  • This component will support functionality to detect intersections.

4. Dependencies on Other Framework Components

  • Zend_Exception
  • SPL Iterator
  • SPL Exceptions

5. Theory of Operation

This component can be used as is. It can be used to do calculations.

6. Milestones / Tasks

  • Milestone 1: Setup the proposal and consider feedback.
  • Milestone 2: Write and finish component source code.
  • Milestone 3: Write unit tests
  • Milestone 4: Write documentation

7. Class Index

  • Zend_Math
  • Zend_Math_BoundingBox
  • Zend_Math_BoundingFrustum
  • Zend_Math_BoundingSphere
  • Zend_Math_BoundingVolume
  • Zend_Math_Exception
  • Zend_Math_Exception_DivideByZero
  • Zend_Math_Interface
  • Zend_Math_Matrix
  • Zend_Math_Matrix_Matrix44
  • Zend_Math_Plane
  • Zend_Math_Point
  • Zend_Math_Quaternion
  • Zend_Math_Ray
  • Zend_Math_Rectangle
  • Zend_Math_Size
  • Zend_Math_Vector
  • Zend_Math_Vector_Vector2
  • Zend_Math_Vector_Vector3
  • Zend_Math_Vector_Vector4

8. Use Cases

UC-01
UC-02

9. Class Skeletons

The code for this proposal can be found at http://code.google.com/p/zend-math/source/browse/

]]></ac:plain-text-body></ac:macro>

]]></ac:plain-text-body></ac:macro>

Labels:
math math Delete
vector vector Delete
matrix matrix Delete
algebra algebra Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Jun 02, 2011

    <p>You should write your code in PHP5.3 style for ZF2 (namespace, refactor exceptions, ...).</p>

    <p>I think it would be more readable if you use tabs for skeletons.</p>

  2. Jun 02, 2011

    <p>I very much like the Zend_Math idea, but I agree that it should be coded against ZF2 PHP 5.3<br />
    as far as I understand ZF1 is in feature freeze state</p>

    <p>few other points:</p>
    <ul>
    <li>I don't like the idea of forcing user to use precision defined in class const<br />
    not every calculation needs PI with 50 digits precision<br />
    so I guess it would be nice to have Zend\Math::setPrecision() to set precisions for all calculations performed by Zend\Math</li>
    </ul>

    <ul>
    <li>not sure about naming and namespaces at all<br />
    Math is a very broad namespace, so mabe it's good idea to separate linear algebra from geometry namespace<br />
    and mabe even separate geometry into 2d & 3d namespaces</li>
    </ul>

    <ul>
    <li>personally don't like that Matrix, Vector etc objects are both data containers and utility classes</li>
    </ul>

    <p>so I prefer something like:</p>
    <ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
    $a = new \Zend\Math\Matrix(array(...));
    $b = new \Zend\Math\Matrix(array(...));
    $c = Zend\Math\Matrix\Utils:add($a, $c);
    ]]></ac:plain-text-body></ac:macro>

    <p>over</p>

    <ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
    $a = new \Zend\Math\Matrix(array(...));
    $b = new \Zend\Math\Matrix(array(...));
    $c = $a->add($b);
    ]]></ac:plain-text-body></ac:macro>

  3. Jun 04, 2011

    <p>Hi Benoît and Denis,</p>

    <p>Thank you very much for your feedback. I have moved the code to Google Code since that makes reviewing easier. I just put everything in the Zend\Math namespace. I'm pretty new to this new style so if I missed anything while converting the code, just let me know.</p>

    <p>Denis, I'd like to respond to your feedback:</p>

    <p>1. Is there a performance issue when using this amount of digits behind the comma? If not I do not see a problem to have it like this since I can't imagine anyone to like loosing performance during calculations. If one does not want this amount of digits one can use the appropriate PHP function to show the preferred amount of digits. But again, if there is a performance issue it should be changed.</p>

    <p>2. I agree with you about the naming of the namespaces. Math is indeed very broad but I am not creative enough to come with good names. Any suggestion is welcome.</p>

    <p>3. Vectors and matrices are very dynamic. That is the reason that I made those two classes. The Vector2, Vector3, Vector4 and Matrix44 classes are there since they are used very often during game development for example. You could call them "helpers" I think. I do see the point you are making though and I am not sure how to solve it. I would like to hear more ideas about that.<br />
    The example you made is not entirely correct. Once one uses class methods, it should be clear that they change something on the instance of the class. The add, sub, mul and div methods are doing that.<br />
    My opinion is that static methods should be used as factory methods where new instances are created. The cross product method should be a static method I think. I do not like the idea to create a Utils class. That might complicate code writing...</p>

    <p>Thanks again for your feedback guys!</p>

  4. Jun 05, 2011

    <p>Hi Walter</p>

    <ul class="alternate">
    <li>on precision, I did some benchmarks<br />
    there is some performance hit with higher pricision numbers, <br />
    it's insignificant though, so i guess predefined precision values are ok</li>
    </ul>

    <ul class="alternate">
    <li>on namespaces, my main concern was Math_Interface wich defines add/sub/div/mul methods<br />
    take a look at ZF2 coding standards Interfaces section <a class="external-link" href="http://framework.zend.com/wiki/display/ZFDEV2/ZF+2.0+Coding+Standards+Addendums">http://framework.zend.com/wiki/display/ZFDEV2/ZF+2.0+Coding+Standards+Addendums</a><br />
    so basically according to ZF2 standards there should be an interface to define math entities, or math operations<br />
    but not the whole math namespace</li>
    </ul>

    <p>so with your approach it's something like</p>

    <ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
    namespace Zend\Math;
    interface Entity

    Unknown macro: { public function add( $value ); public function sub( $value ); ... } namespace ZendMath;class Matrix implements Entity, Iterator{}

    ]]></ac:plain-text-body></ac:macro>

    <ul class="alternate">
    <li>on Matrix/Vector operations,<br />
    there are severall approaches<br />
    1) <code>$a->mul($b);</code> multiplication of $a & $b changes $a<br />
    2) <code>$c = $a->mul($b);</code> multiplication of $a & $b creates new object $c, leaving $a intact<br />
    3) <code>$op = new Zend\Math\Matrix\Op(); $c = $op->mul($a, $b);</code> separate class to manipulate objects, leaves $a intact<br />
    what I was saying is my personal preference is to separate manipulation class<br />
    the problem I see with your approach, is let's say multiplication of matrices with difeerent dimentions<br />
    A<ac:link><ri:page ri:content-title="m x n" /></ac:link> * B<ac:link><ri:page ri:content-title="n x k" /></ac:link> = C<ac:link><ri:page ri:content-title="m x k" /></ac:link> wich is ok since number of cols in A equals numbers of rows in B <br />
    with your approach, after $a->mul($b) object $a was originally <ac:link><ri:page ri:content-title="m x n" /></ac:link> becomes <ac:link><ri:page ri:content-title="m x k" /></ac:link></li>
    </ul>

    <p>also with separate class you can have a correct interface definition, let's say</p>

    <ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
    namespace Zend\Math;
    interface Op
    {
    public function add( $value1, $value2 );
    public function sub( $value, $value2 );
    }

    namespace Zend\Math;
    class Matrix\Op implemets Op
    {
    }
    ]]></ac:plain-text-body></ac:macro>

    <p>but again, it's just my personal preference<br />
    I've checked some Java and C++ classes and there is no general way </p>

    <p>anyway, bottom line is<br />
    since Math is a broad namespace, and there is nothing remotely close in current ZF<br />
    I think you need more community input</p>

    <p>I personnaly interested in geometry stuff, point, polyline, rectanle, plane etc<br />
    so let me know if you need any help with that</p>

  5. Jun 19, 2011

    <ol>
    <li>I can't really see any advantage to the VectorX and MatrixXY classes. They make me think of "bad design". Instead, I'd rather have some kind of Factory to create such objects. Other options include identity matrices, random matrices, ...</li>
    <li>A Vector is basically a Matrix with only one Column. Why implement it twice? I would rather extend Matrix for that purpose.</li>
    <li>I don't know why a Matrix must be identity on creation. I'd rather create a zero matrix and provide a static method to create an identity matrix. This also refers to the factory mentioned earlier.</li>
    <li>The dimension checks for calculations are way to weak. You simply cannot subtract a 2x2 matrix from a 3x3 matrix. The dimensions must match. Also, a 1x1 matrix is a scalar: you should cover that.</li>
    <li>I am missing some key functionality like inverse matrices (although that's a numerical tough one), row reducing methods, rank, ... also more advanced stuff as eigenvalues and eigenvectors, ... (you never knwo who is going to use it, but I'd put these at the bottom of the todo-list <ac:emoticon ac:name="wink" />)</li>
    <li>The operators are all in one interface. Might be useful, but don't know if it is the way to go (Like Dennis suggests). I'd rather make more interfaces for operations. I think Anonymous functions are perfect for this (There is a webinar from Matthew Weier O'Phinney on this subject: <a class="external-link" href="http://www.zend.com/en/webinar/PHP/70170000000bYYX-webinar-anonymous-functions-in-php-53-20110426.flv">http://www.zend.com/en/webinar/PHP/70170000000bYYX-webinar-anonymous-functions-in-php-53-20110426.flv</a>). Also, make sure all operations are consistent (either they all change the arguments or either all return new objects. Personally, I prefer the last one (I hate Zend_Date for that reason).</li>
    <li>I would also refactor methods like getRows() and getColumns() to getNbRobs() and getNbColumns() because I expect getColumns() to give me the Columns as Vectors and getRows() the Rows as vectors. That also something I'm missing: the functionality to extract a row or column (with or without modifying the original object (extract/extract&remove)). It might be useful.</li>
    <li>Math is indeed a very broad namespace. A LinearAlgebra namespace might be a good idea.</li>
    </ol>

    <p>I Think that's about it <ac:emoticon ac:name="smile" /></p>