Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Target objects #11

Merged
merged 4 commits into from
Dec 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ numpy==1.25.2
matplotlib==3.7.2
scipy==1.11.1
sympy==1.12
.
attrs==23.1.0
-e .
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ install_requires =
scipy>=1
sympy>=1
matplotlib>=3
attrs>=23
python_requires = >=3.7
package_dir =
=src
Expand Down
33 changes: 18 additions & 15 deletions src/doptics/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,16 @@ def probability_density(x): return source_density(x) / (sp.integrate.quad(source
return distr_samples


def construct_y_spans(small_angle: float, large_angle: float) -> Tuple[ArrayLike]:
def construct_y_spans(small_angle: float, large_angle: float, offset: float=0) -> Tuple[ArrayLike]:
r"""
Construct the interval targets for point targets with an angular lighting distribution.

Make sure that the absolute value $\vert small_angle - large_angle \vert < \pi$

:param small_angle: in radians, somewhere between $-\pi$ and $\pi$.
:param large_angle: in radians, somewhere between $-\pi$ and $\pi$.
:return: intervals y1_span and y2_span which are hit by the light rays which hit the target
:param offset: float
:return: intervals y1_span and y2_span IN RADIANS!!!
"""
abs_small_angle = small_angle if np.abs(np.sin(small_angle)) < np.abs(np.sin(large_angle)) else large_angle
abs_large_angle = small_angle if np.abs(np.sin(small_angle)) > np.abs(np.sin(large_angle)) else large_angle
Expand All @@ -100,7 +101,7 @@ def construct_y_spans(small_angle: float, large_angle: float) -> Tuple[ArrayLike
y2_span = np.sort(
np.array([np.cos(large_angle), np.cos(small_angle) * np.sin(abs_large_angle) / np.sin(abs_small_angle)])
)
return (y1_span, y2_span)
return (y1_span - offset, y2_span - offset)


def construct_target_density_intervals_from_angular(angle_density: Callable,
Expand Down Expand Up @@ -131,21 +132,19 @@ def construct_target_density_intervals_from_angular(angle_density: Callable,
ic(np.cos(small_angle))
ic(np.cos(large_angle))

y1_span, y2_span = construct_y_spans(small_angle, large_angle)

# y1_span = np.array([np.cos(small_angle), np.cos(large_angle) * np.sin(abs_small_angle)/np.sin(abs_large_angle)])
# y2_span = np.sort(
# np.array([np.cos(large_angle), np.cos(small_angle) * np.sin(abs_large_angle)/np.sin(abs_small_angle)])
# )

ic(y1_span)
ic(y2_span)

y1_span, y2_span = construct_y_spans(small_angle, large_angle)
if l1 == l2:
l2 = 1.4 * l2
y2_span[0] = 1.4 * y2_span[0]
y2_span[1] = 1.4 * y2_span[1]

y1_span = y1_span + midpoint[0]
y2_span = y2_span + midpoint[0]
ic(y1_span)
ic(y2_span)

def y1_density(y1):
Expand All @@ -163,12 +162,10 @@ def y2_density(y2):
# for i in np.linspace(small_angle, large_angle, 100):
# print(f'y2({i}) = {y2_density(i)}')

y1_span = y1_span + midpoint[0]
y2_span = y2_span + midpoint[0]
for j in np.linspace(y2_span[0], y2_span[1], 100):
print(f'arg to take arccos from = {j / np.linalg.norm([j - midpoint[0], l2 - midpoint[1]])}')
print(f'{y1_span[0]}pppppp{y1_density(y1_span[1])}')
print(f'qqqqqqq{y2_density(y2_span[0])}')
# for j in np.linspace(y2_span[0], y2_span[1], 100):
# print(f'arg to take arccos from = {j / np.linalg.norm([j - midpoint[0], l2 - midpoint[1]])}')
# print(f'{y1_span[0]}pppppp{y1_density(y1_span[1])}')
# print(f'qqqqqqq{y2_density(y2_span[0])}')
return y1_density, y2_density, y1_span, y2_span, l1 + midpoint[1], l2 + midpoint[1]


Expand All @@ -190,3 +187,9 @@ def rescaling_target_distribution() -> None:
integral_y1 = appropriate_g_factor * sc.integrate.quad(g, yl, yr)[0]
print(integral_x[0])
print(integral_y1)


def function_equality_checker(true_func: Callable, test_func: Callable, domain: ArrayLike):
sample = (domain[1] - domain[0]) * np.random.Generator.random() + domain[0]

return False
61 changes: 61 additions & 0 deletions src/doptics/target.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,64 @@
from attrs import define
from typing import Callable
import numpy as np
import doptics

@define
class Target:
y1_span: [float, float]
y2_span: [float, float]
l1: float
l2: float
y1_density: Callable
y2_density: Callable
ray_crossing: []


@define
class PointTarget(Target):
midpoint: [float, float]
angle_density: Callable

def __init__(self, angle_density, small_angle, large_angle, midpoint):
abs_small_angle = small_angle if np.abs(np.sin(small_angle)) < np.abs(np.sin(large_angle)) else large_angle
abs_large_angle = small_angle if np.abs(np.sin(small_angle)) > np.abs(np.sin(large_angle)) else large_angle
l1 = round(np.sin(abs_small_angle), 5)
l2 = round(np.sin(abs_large_angle), 5)
y1_span, y2_span = doptics.functions.construct_y_spans(small_angle, large_angle)
if l1 == l2:
l2 = 1.4 * l2
y2_span[0] = 1.4 * y2_span[0]
y2_span[1] = 1.4 * y2_span[1]
self.y1_span = y1_span + midpoint[0]
self.y2_span = y2_span + midpoint[0]
self.l1 = l1 + midpoint[1]
self.l2 = l2 + midpoint[1]
self.midpoint = midpoint
self.angle_density = angle_density

# create y1_density and y2_density

def y1_density(y1):
return (angle_density(np.arccos(y1 / np.linalg.norm(np.array(
[y1 - midpoint[0], l1 - midpoint[1]], dtype=object)))) /
np.linalg.norm(np.array([y1 - midpoint[0], l1 - midpoint[1]], dtype=object))
)

def y2_density(y2):
return (angle_density(np.arccos(y2 / np.linalg.norm(np.array(
[y2 - midpoint[0], l2 - midpoint[1]], dtype=object)))) /
np.linalg.norm(np.array([y2 - midpoint[0], l2 - midpoint[1]], dtype=object))
)
self.y1_density = y1_density
self.y2_density = y2_density

@define
class IntervallTarget(Target):

def __init__(self, y1_span, y2_span, l1, l2, source_density, l_source):
self.y1_span = y1_span
self.y2_span = y2_span
self.l1 = l1
self.l2 = l2


2 changes: 0 additions & 2 deletions src/doptics/two_mirrors.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,6 @@ def starting_density_rescaled(x): return 1 / ax * starting_density(x)
def solve_two_mirrors_parallel_source_point_target(starting_density: Callable, target_distribution_1: Callable,
target_distribution_2,
x_span: Union[List[float], Tuple[float, float]],
# y1_span: List[float],
# y2_span: List[float],
u0: float, w0: float, l1: float, l2: float,
number_rays=15,
color: str = 'szegedblue') -> List[dict]:
Expand Down
35 changes: 35 additions & 0 deletions tests/test_target.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import doptics.functions as func
import doptics.target as tg
import numpy as np
from typing import Callable
from icecream import ic


def test_point_target_construction():
angle_density = func.uniform
small_angle = -0.9
large_angle = -0.2
midpoint = (12, 2.3)

targ = tg.PointTarget(
angle_density=angle_density,
small_angle=small_angle,
large_angle=large_angle,
midpoint=midpoint
)

y2_density, y1_density, y1_span, y2_span, l1, l2 = func.construct_target_density_intervals_from_angular(
angle_density=angle_density,
small_angle=small_angle,
large_angle=large_angle,
midpoint=midpoint
)

# assert targ.y1_density == y1_density
# assert targ.y2_density == y2_density
assert np.array_equiv(targ.y1_span, y1_span)
assert np.array_equiv(targ.y2_span, y2_span)
assert (targ.y1_span == y1_span).all()
assert (targ.y2_span == y2_span).all()
assert targ.l1 == l1
assert targ.l2 == l2
Loading