vectorizer-svg 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,27 @@
1
+ Metadata-Version: 2.4
2
+ Name: vectorizer-svg
3
+ Version: 0.1.0
4
+ Summary: Simple linear algabra library
5
+ Author: 0xSaad
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+
9
+ # Vectorizer-svg
10
+
11
+ Simple Linear Algebra Library with SVG Manipulation
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pip install vectorizer
17
+ ```
18
+
19
+ ## Features
20
+
21
+ - Vectors graph
22
+ - Operations on vectors
23
+ - Gradient vector
24
+
25
+ ### Credits :
26
+
27
+ [0xSaad](https://x.com/0xdonzdev)
@@ -0,0 +1,19 @@
1
+ # Vectorizer-svg
2
+
3
+ Simple Linear Algebra Library with SVG Manipulation
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install vectorizer
9
+ ```
10
+
11
+ ## Features
12
+
13
+ - Vectors graph
14
+ - Operations on vectors
15
+ - Gradient vector
16
+
17
+ ### Credits :
18
+
19
+ [0xSaad](https://x.com/0xdonzdev)
@@ -0,0 +1,15 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "vectorizer-svg"
7
+ version = "0.1.0"
8
+ description = "Simple linear algabra library"
9
+ authors = [{ name="0xSaad"}]
10
+ readme = "README.md"
11
+ requires-python = ">=3.8"
12
+ dependencies = []
13
+
14
+ [tool.setuptools.packages.find]
15
+ where = ["."]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,8 @@
1
+ from .core import Vector, gradient, vector_derivative, plot_vectors
2
+
3
+ __all__ = [
4
+ "Vector",
5
+ "gradient",
6
+ "vector_derivative",
7
+ "plot_vectors"
8
+ ]
@@ -0,0 +1,217 @@
1
+ from math import sqrt
2
+
3
+ class Vector:
4
+ def __init__(self, *coords):
5
+ if len(coords) == 1 and hasattr(coords[0], "__iter__"):
6
+ coords = tuple(coords[0])
7
+ self.coords = tuple(float(c) for c in coords)
8
+ if len(self.coords) == 0:
9
+ raise ValueError("Vector must have at least one component.")
10
+
11
+ def __len__(self):
12
+ return len(self.coords)
13
+
14
+ def __iter__(self):
15
+ return iter(self.coords)
16
+
17
+ def __repr__(self):
18
+ return f"Vector{self.coords}"
19
+
20
+ # عمليات أساسية
21
+ def __add__(self, other):
22
+ other = self._coerce(other)
23
+ return Vector(a + b for a, b in zip(self.coords, other.coords))
24
+
25
+ def __sub__(self, other):
26
+ other = self._coerce(other)
27
+ return Vector(a - b for a, b in zip(self.coords, other.coords))
28
+
29
+ def __neg__(self):
30
+ return Vector(-c for c in self.coords)
31
+
32
+ def __mul__(self, other):
33
+ if isinstance(other, (int, float)):
34
+ return Vector(c * other for c in self.coords)
35
+ raise TypeError("Use v.dot(w) or dot(v,w) for dot product, not v*w.")
36
+
37
+ def __rmul__(self, other):
38
+ return self.__mul__(other)
39
+
40
+ def _coerce(self, other):
41
+ if not isinstance(other, Vector):
42
+ other = Vector(other)
43
+ if len(other) != len(self):
44
+ raise ValueError("Vectors must have same dimension.")
45
+ return other
46
+
47
+ # Dot Product
48
+ def dot(self, other):
49
+ other = self._coerce(other)
50
+ return sum(a * b for a, b in zip(self.coords, other.coords))
51
+
52
+ # Cross Product
53
+ def cross(self, other):
54
+ other = self._coerce(other)
55
+ if len(self) == 3 and len(other) == 3:
56
+ a1, a2, a3 = self.coords
57
+ b1, b2, b3 = other.coords
58
+ return Vector(a2*b3 - a3*b2,
59
+ a3*b1 - a1*b3,
60
+ a1*b2 - a2*b1)
61
+ elif len(self) == 2 and len(other) == 2:
62
+ a1, a2 = self.coords
63
+ b1, b2 = other.coords
64
+ return a1*b2 - a2*b1
65
+ else:
66
+ raise ValueError("Cross product defined for 2D (scalar) or 3D vectors.")
67
+
68
+ # Norm + Unit Vector
69
+ def norm(self):
70
+ return sqrt(sum(c*c for c in self.coords))
71
+
72
+ def unit(self):
73
+ n = self.norm()
74
+ if n == 0:
75
+ raise ValueError("Zero vector has no unit direction.")
76
+ return (1.0 / n) * self
77
+
78
+ def to2d(self):
79
+ if len(self) == 2:
80
+ return self
81
+ elif len(self) >= 2:
82
+ return Vector(self.coords[0], self.coords[1])
83
+ else:
84
+ raise ValueError("Cannot project 1D or empty vector to 2D")
85
+
86
+
87
+
88
+ def gradient(f, point, h=1e-5):
89
+
90
+
91
+ point = tuple(float(x) for x in point)
92
+ n = len(point)
93
+ partials = []
94
+ for i in range(n):
95
+ forward = list(point)
96
+ backward = list(point)
97
+ forward[i] += h
98
+ backward[i] -= h
99
+ df = f(forward) - f(backward)
100
+ partials.append(df / (2*h))
101
+ return Vector(partials)
102
+
103
+
104
+ def vector_derivative(F, t, h=1e-5):
105
+
106
+
107
+ ft_plus = F(t + h)
108
+ ft_minus = F(t - h)
109
+ if not isinstance(ft_plus, Vector):
110
+ ft_plus = Vector(ft_plus)
111
+ if not isinstance(ft_minus, Vector):
112
+ ft_minus = Vector(ft_minus)
113
+ return (1.0 / (2*h)) * (ft_plus - ft_minus)
114
+
115
+
116
+
117
+
118
+
119
+ def plot_vectors(vectors, width=600, height=600, padding=60,
120
+ axis_range=None, show_coords=True, show_grid=True,
121
+ tick_count=7):
122
+
123
+ vs = [v if isinstance(v, Vector) else Vector(v) for v in vectors]
124
+ vs2d = [v.to2d() for v in vs]
125
+
126
+ xs = [0.0]; ys = [0.0]
127
+ for v in vs2d:
128
+ xs.append(v.coords[0]); ys.append(v.coords[1])
129
+
130
+ if axis_range is None:
131
+ xmin, xmax = min(xs), max(xs)
132
+ ymin, ymax = min(ys), max(ys)
133
+
134
+ if xmin == xmax: xmin -= 1; xmax += 1
135
+ if ymin == ymax: ymin -= 1; ymax += 1
136
+
137
+ dx = xmax - xmin; dy = ymax - ymin
138
+ xmin -= 0.3 * dx; xmax += 0.3 * dx
139
+ ymin -= 0.3 * dy; ymax += 0.3 * dy
140
+ else:
141
+ xmin, xmax, ymin, ymax = axis_range
142
+
143
+ def map_point(x, y):
144
+ sx = padding + (x - xmin) / (xmax - xmin) * (width - 2*padding)
145
+ sy = height - (padding + (y - ymin) / (ymax - ymin) * (height - 2*padding))
146
+ return sx, sy
147
+
148
+ svg = []
149
+ svg.append(f'<svg xmlns="http://www.w3.org/2000/svg" width="{width}" height="{height}" '
150
+ f'style="font-family: sans-serif;">')
151
+
152
+ svg.append("""
153
+ <defs>
154
+ <marker id="arrow" markerWidth="10" markerHeight="10" refX="5" refY="5"
155
+ orient="auto" markerUnits="strokeWidth">
156
+ <path d="M0,0 L10,5 L0,10 z" fill="blue"/>
157
+ </marker>
158
+ </defs>""")
159
+
160
+ svg.append('<rect x="0" y="0" width="100%" height="100%" fill="white"/>')
161
+
162
+ ox, oy = map_point(0, 0)
163
+
164
+ xticks = [xmin + i*(xmax-xmin)/(tick_count-1) for i in range(tick_count)]
165
+ yticks = [ymin + i*(ymax-ymin)/(tick_count-1) for i in range(tick_count)]
166
+
167
+ if show_grid:
168
+ for x in xticks:
169
+ sx, _ = map_point(x, 0)
170
+ svg.append(f'<line x1="{sx}" y1="{padding}" x2="{sx}" y2="{height-padding}" stroke="#eeeeee"/>')
171
+ for y in yticks:
172
+ _, sy = map_point(0, y)
173
+ svg.append(f'<line x1="{padding}" y1="{sy}" x2="{width-padding}" y2="{sy}" stroke="#eeeeee"/>')
174
+
175
+
176
+
177
+
178
+ x0,_ = map_point(xmin, 0)
179
+ x1,_ = map_point(xmax, 0)
180
+ _,y0 = map_point(0, ymin)
181
+ _,y1 = map_point(0, ymax)
182
+
183
+
184
+
185
+
186
+ svg.append(f'<line x1="{x0}" y1="{oy}" x2="{x1}" y2="{oy}" stroke="black" stroke-width="2"/>')
187
+ svg.append(f'<line x1="{ox}" y1="{y0}" x2="{ox}" y2="{y1}" stroke="black" stroke-width="2"/>')
188
+
189
+
190
+ for x in xticks:
191
+ sx, sy = map_point(x, 0)
192
+ svg.append(f'<line x1="{sx}" y1="{oy-5}" x2="{sx}" y2="{oy+5}" stroke="black" stroke-width="1.2"/>')
193
+ svg.append(f'<text x="{sx-10}" y="{oy+20}" font-size="14" fill="black" font-family="sans-serif">{x:.1f}</text>')
194
+
195
+ for y in yticks:
196
+ sx, sy = map_point(0, y)
197
+ svg.append(f'<line x1="{ox-5}" y1="{sy}" x2="{ox+5}" y2="{sy}" stroke="black" stroke-width="1.2"/>')
198
+ svg.append(f'<text x="{ox+10}" y="{sy+5}" font-size="14" fill="black" font-family="sans-serif">{y:.1f}</text>')
199
+
200
+
201
+
202
+
203
+
204
+
205
+
206
+ # Vectors
207
+ for v in vs2d:
208
+ x, y = v.coords
209
+ sx, sy = map_point(x, y)
210
+ svg.append(f'<line x1="{ox}" y1="{oy}" x2="{sx}" y2="{sy}" stroke="blue" stroke-width="2.5" marker-end="url(#arrow)"/>')
211
+
212
+ if show_coords:
213
+ svg.append(f'<text x="{sx+8}" y="{sy-8}" font-size="13" font-family="sans-serif">'
214
+ f'({x:.2f}, {y:.2f})</text>')
215
+
216
+ svg.append("</svg>")
217
+ return "\n".join(svg)
@@ -0,0 +1,27 @@
1
+ Metadata-Version: 2.4
2
+ Name: vectorizer-svg
3
+ Version: 0.1.0
4
+ Summary: Simple linear algabra library
5
+ Author: 0xSaad
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+
9
+ # Vectorizer-svg
10
+
11
+ Simple Linear Algebra Library with SVG Manipulation
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pip install vectorizer
17
+ ```
18
+
19
+ ## Features
20
+
21
+ - Vectors graph
22
+ - Operations on vectors
23
+ - Gradient vector
24
+
25
+ ### Credits :
26
+
27
+ [0xSaad](https://x.com/0xdonzdev)
@@ -0,0 +1,8 @@
1
+ README.md
2
+ pyproject.toml
3
+ vectorizer-svg/__init__.py
4
+ vectorizer-svg/core.py
5
+ vectorizer_svg.egg-info/PKG-INFO
6
+ vectorizer_svg.egg-info/SOURCES.txt
7
+ vectorizer_svg.egg-info/dependency_links.txt
8
+ vectorizer_svg.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ dist
2
+ vectorizer-svg