001    /**
002     * BladeTreeSet.java
003     *
004     * This file is part of jclifford package and it's distributed under the terms of the MIT license.
005     *
006     * The MIT License :
007     * -----------------
008     * Copyright (c) 2002, 2003, 2004, 2005 Giorgio Vassallo, Pietro Brignola
009     *
010     * Permission is hereby granted, free of charge, to any person obtaining a
011     * copy of this software and associated documentation files (the "Software"),
012     * to deal in the Software without restriction, including without limitation
013     * the rights to use, copy, modify, merge, publish, distribute, sublicense,
014     * and/or sell copies of the Software, and to permit persons to whom the
015     * Software is furnished to do so, subject to the following conditions:
016     * The above copyright notice and this permission notice shall be included in
017     * all copies or substantial portions of the Software.
018     *
019     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
020     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
021     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
022     * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
023     * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
024     * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
025     * DEALINGS IN THE SOFTWARE.
026     */
027    
028    package jclifford;
029    
030    import java.util.Iterator;
031    import java.util.TreeSet;
032    
033    /**
034     * <p>This class represents a TreeSet implementation of a blade (wedge product of generic basis versors).</p>
035     * <p>It is an utility class for the CliffordTreeSet class.</p>
036     * @version <p>0.9</p>
037     * @author <p>Realized by <a href="mailto:vassallo@csai.unipa.it">Giorgio Vassallo</a>, <a href="mailto:pietro.brignola@libero.it">Pietro Brignola</a>, November 2002.</p>
038     * @see Blade
039     * @see BladeBitSet
040     */
041    public class BladeTreeSet implements Comparable{
042    
043            /**
044             * Tree set of the versors present in this blade. Empty blade represents a scalar.
045             */
046            private TreeSet treeset;
047    
048            /**
049             * Creates and returns an new empty blade representing a scalar.
050             */
051            public BladeTreeSet()
052            {
053                    treeset = new TreeSet();
054            }
055    
056            /**
057             * Creates and returns an new Object deeply cloning this Object.
058             */
059            public Object clone()
060            {
061                    //Creating a new empty blade
062                    BladeTreeSet newbld = new BladeTreeSet();
063                    //Defining an iterator on versors
064                    Iterator it = treeset.iterator();
065                    //For all versors
066                    while(it.hasNext())
067                            //Adding a copy to newbld
068                            newbld.treeset.add(((Versor) it.next()).clone());
069                    //Returning new Object
070                    return newbld;
071            }
072    
073            /**
074             * Puts specified versor in this blade if it is not already present.
075             * @param versor the specified versor to be put to the blade.
076             */
077            public void put(int versor)
078            {
079                    treeset.add(new Versor(versor));
080            }
081    
082            /**
083             * Compare this object with another comparing versors.
084             */
085            public int compareTo(Object object)
086            {
087                    BladeTreeSet bld = (BladeTreeSet) object;
088                    int result;
089                    int grade1 = treeset.size();
090                    int grade2 = bld.treeset.size();
091                    //Comparing grades
092                    if(grade1 < grade2)
093                            return -1;
094                    if(grade1 > grade2)
095                            return 1;
096                    //Comparing versors
097                    Iterator it1 = treeset.iterator();
098                    Iterator it2 = bld.treeset.iterator();
099                    while(it1.hasNext()){
100                            result = ((Versor) it1.next()).compareTo((Versor) it2.next());
101                            if(result!=0)
102                                    return result;
103                    }
104                    //Blades are equals
105                    return 0;
106            }
107    
108            /**
109             * Returns the grade of this blade.
110             * @return the grade of the blade.
111             */
112            public int getGrade()
113            {
114                    return treeset.size();
115            }
116    
117            /**
118             * Computes the sign of the product with the specified blade.
119             * @param bld the second blade of the product.
120             * @return true if the sign of the product with the specified blade is negative, false otherwise.
121             */
122            boolean getSign(BladeTreeSet bld)
123            {
124                    int sign = 0;
125                    int count = 0;
126                    //Indexes
127                    int i1, i2, ix = 0;
128                    //Defining ordered arrays of versors
129                    Versor[] arrvers1 = (Versor[]) treeset.toArray(new Versor[0]);
130                    Versor[] arrvers2 = (Versor[]) bld.treeset.toArray(new Versor[0]);
131                    //Counting versors swapping
132                    for(i1 = 0; i1 < arrvers1.length; ++i1){
133                            sign ^= (count & 1);
134                            for(i2 = ix; (i2<arrvers2.length)&&((arrvers2[i2]).versor<arrvers1[i1].versor);++i2){
135                                    sign ^= 1;
136                                    ++count;
137                            }
138                            ix = i2;
139                    }
140                    return sign != 0;
141            }
142    
143            /**
144             * Computes the geometric product with the specified blade.
145             * @param bld the second blade of the geometric product.
146             * @return new blade from the geometric product with the specified blade.
147             */
148            BladeTreeSet geometricProduct(BladeTreeSet bld)
149            {
150                    BladeTreeSet bld1 = (BladeTreeSet) clone();
151                    BladeTreeSet bld2 = (BladeTreeSet) bld.clone();
152                    BladeTreeSet newbld = (BladeTreeSet) clone();
153                    newbld.treeset.removeAll(bld2.treeset);
154                    bld2.treeset.removeAll(bld1.treeset);
155                    newbld.treeset.addAll(bld2.treeset);
156                    return newbld;
157            }
158    
159            /**
160             * Computes the wedge product with the specified blade.
161             * @param bld the second blade of the wedge product.
162             * @return null if blades have common versors or a new blade from the wedge product with the specified blade.
163             */
164            BladeTreeSet wedgeProduct(BladeTreeSet bld)
165            {
166                    BladeTreeSet newbld = (BladeTreeSet) clone();
167                    newbld.treeset.retainAll(bld.treeset);
168                    if(! newbld.treeset.isEmpty())
169                            return null;
170                    newbld = (BladeTreeSet) clone();
171                    newbld.treeset.addAll(bld.treeset);
172                    return newbld;
173            }
174    
175            /**
176             * Computes the left contraction with the specified blade.
177             * @param bld the second blade of the left contraction.
178             * @return null if versors are not a subset of the specified blade, or a new blade from the left contraction with the specified blade.
179             */
180            BladeTreeSet leftContraction(BladeTreeSet bld)
181            {
182                    if(! bld.treeset.containsAll(treeset))
183                            return null;
184                    BladeTreeSet newbld = (BladeTreeSet) bld.clone();
185                    newbld.treeset.removeAll(treeset);
186                    return newbld;
187            }
188    
189            /**
190             * Computes the rignt contraction with the specified blade.
191             * @param bld the second blade of the right contraction.
192             * @return null if versors of the specified blade are not a subset of this blade, or a new blade from the left contraction with the specified blade.
193             */
194            BladeTreeSet rigthContraction(BladeTreeSet bld)
195            {
196                    if(! treeset.containsAll(bld.treeset))
197                            return null;
198                    BladeTreeSet newbld = (BladeTreeSet) clone();
199                    newbld.treeset.removeAll(bld.treeset);
200                    return newbld;
201            }
202    
203            /**
204             * Returns a string representation of this blade.
205             * @return the string representation of this blade.
206             */
207            public String toString()
208            {
209                    //String representation of the blade
210                    String str = new String();
211                    //Defining an iterator on versors
212                    Iterator it = treeset.iterator();
213                    //For all blade-value mappings
214                    while(it.hasNext())
215                            str += ((Versor) it.next()).toString();
216                    //Scalar case
217                    if(str.length() == 0)
218                            str += "scalar";
219                    //Returning the string
220                    return str;
221            }
222    
223    }