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 }