## reference request – Essential spectrum of multiplication operator

Let $$ain mathcal{L}(L^2((0, 1))$$ be a multiplication operator. I wonder whether there is any work on calculating its essential spectrum. Is there any way to explicitly compute its essential growth bound and elements of its discrete spectrum? What about the $$n$$-dimensional case, i.e., $$ain mathcal{L}(L^2((0, 1), mathbb{R}^{ntimes n})$$?

## javascript – Why is my app failing in a conditional operator?

my code is

``````export default function useFetch(fetchFunction, param) {
const cache = useContext(cacheContext);
const (state, dispatch) = useReducer(fetchReducer, initialValue);
useEffect(() => {
if (cache.page(param)) {
dispatch({ type: ACTIONS.success, payload: cache.page(param) });
console.log("cache");
return;
}
// other code below
)
``````

But my app is failing in the conditional operator. Im expecting that if cache.page(param) is empty, keep executing the code below. For example, if i got the param `"0"` i get the error `"TypeError: Cannot read property '0' of null"` and my app crashes

## python – NotImplementedError: Operator ‘getitem’ is not supported on this expression

I wrote an SQL query to create a view for the database I’m working on and the query works as expected:

``````CREATE OR REPLACE VIEW public.current_model
AS SELECT pm.model_id,
mp.name,
ga.pit,
pm.description,
pm.created_datetime,
pm.folder_full_path,
pm.status
FROM prediction_model pm
JOIN material_property mp ON pm.property_id = mp.auto_id
JOIN geographic_applicability ga ON ga.model_id = pm.auto_id
WHERE pm.status::text <> 'INACTIVE'::text AND (pm.created_datetime IN ( SELECT max(pm2.created_datetime) AS max
FROM prediction_model pm2
JOIN geographic_applicability ga2 ON ga2.model_id = pm2.auto_id
JOIN material_property mp2 ON pm2.property_id = mp2.auto_id
GROUP BY mp2.name, ga2.pit));
``````

Now I need to add this view to the sqlalchemy schema for the database. I have successfully implemented couple other views, but this one gets me lost (mind you, I have almost no previous sqlalchemy experience). This is what I have come up with so far:

``````    @classmethod
def current_model_view(cls):
j1 = cls.prediction_model.join(cls.material_property,
cls.prediction_model.c.property_id == cls.material_property.c.auto_id)
j2 = j1.join(cls.geographic_applicability,
cls.prediction_model.c.auto_id == cls.geographic_applicability.c.model_id)

s1 = cls.prediction_model.join(cls.geographic_applicability,
cls.geographic_applicability.c.model_id == cls.prediction_model.c.auto_id)
s2 = s1.join(cls.material_property, cls.prediction_model.c.property_id == cls.material_property.c.auto_id)

max_date = select(max(cls.prediction_model.c.created_datetime)).
select_from(s2).group_by(cls.material_property.c.name, cls.geographic_applicability.c.pit)

view_selectable = select((cls.material_property.c.name,
cls.geographic_applicability.c.pit,
cls.prediction_model.c.description,
cls.prediction_model.c.created_datetime,
cls.prediction_model.c.folder_full_path,
cls.prediction_model.c.status)).
select_from(j2).
where(and_(not_(cls.prediction_model.c.status == 'INACTIVE'),
cls.prediction_model.c.created_datetime.in_(max_date)))
return view_selectable
``````

But this gives me the following error:

``````Traceback (most recent call last):
File "C:/python/mhi_versionist/mhi_versionist/data_base/tracker_database_schema.py", line 320, in <module>
create_view('current_model', ModelDB.current_model_view(), ModelDB.model_db_meta)
File "C:/python/mhi_versionist/mhi_versionist/data_base/tracker_database_schema.py", line 154, in current_model_view
max_date = select(max(cls.prediction_model.c.created_datetime)).
File "C:pythonmhi_versionistvenv2libsite-packagessqlalchemysqloperators.py", line 432, in __getitem__
return self.operate(getitem, index)
File "C:pythonmhi_versionistvenv2libsite-packagessqlalchemysqlelements.py", line 762, in operate
return op(self.comparator, *other, **kwargs)
File "C:pythonmhi_versionistvenv2libsite-packagessqlalchemysqloperators.py", line 432, in __getitem__
return self.operate(getitem, index)
File "<string>", line 1, in <lambda>
File "C:pythonmhi_versionistvenv2libsite-packagessqlalchemysqltype_api.py", line 67, in operate
return o(0)(self.expr, op, *(other + o(1:)), **kwargs)
File "C:pythonmhi_versionistvenv2libsite-packagessqlalchemysqldefault_comparator.py", line 237, in _getitem_impl
_unsupported_impl(expr, op, other, **kw)
File "C:pythonmhi_versionistvenv2libsite-packagessqlalchemysqldefault_comparator.py", line 241, in _unsupported_impl
raise NotImplementedError(
NotImplementedError: Operator 'getitem' is not supported on this expression
``````

Not sure how to solve this.

## algorithm – Making code faster. BITWISE OR operator

Problem:
Given an array A of N integers, you will be asked Q queries. Each query consists of two integers L and R. For each query, find whether bitwise OR of all the array elements between indices L and R is even or odd.

My approach:
Accept the array of N integers. For any query (Qi) scan the array of integers between the given limit. If an odd number is found (x%2==1) then raise a flag and terminate scanning. If flag is found raised tell that the result is odd, else say that it’s even.

On thinking further, I find myself at the dead end. I can’t optimize the code anymore. Only thing I can think of is instead of doing mod 2 I will check the last digit of each number and see if it is one of (0,2,4,6,8). Upon trying that, the time limit still expired (in context to competitive programming (1); Note: the competition has ended a day ago and results declared). Anyways, my question is to find a better method if it exists or optimize the code below.

I assume that the time complexity is O(nQ) where n is the number of elements in the given range.

Assume array is 1-indexed.
Input
First line consists of two space-separated integers N and Q.
Next line consists of N space-separated array elements.
Next Q lines consist of two space-sepaprated integers L and R in each line.

``````#include<stdio.h>
#pragma GCC optimize("O2")

int main()
{
long int c,d,j,N,Q;
int fagvar=0;
scanf("%ld %ldn",&N,&Q);
int a(N);
int i=0;
while(N--)
{
scanf("%ld",&a(i));
i++;
}
while(Q--)
{
scanf("%ld %ld",&c,&d);
for(j=c-1;j<d;j++)
{
if (a(j)%2==1)
{
fagvar=1;
break;
}
}
if (fagvar==1)
{
printf("%dn",0);
fagvar=0;
}
else
{
printf("%dn",1);
}
}
return 0;
}
``````

## ag.algebraic geometry – How do I take the n-th root of a linear operator?

Suppose I have a vector space $$V/overline{mathbb Q}$$ over some algebraically closed field and a semi-simple operator $$T$$ on it with eigenvalues $$alpha_1,dots,alpha_r$$ such that $$|alpha_i| = 1$$ under every complex embedding.

Is there a nice (functorial?) way to define a vector space $$V^{1/n}$$ of dimension $$n$$ with an operator $$T^{1/n}$$ with eigenvalues $$alpha_1^{1/n},dots,alpha_r^{1/n}$$ (where we take all possible roots)?

(Motivation: I came across Abelian varieties over finite fields where the corresponding Frobenius operators have the above relation.)

## representation theory – The generalised Casimir operator \$Omega :Vrightarrow V\$ and \$u:Vrightarrow V\$ commutes

My question regards some of the steps in the proof of theorem 19.9 in Carters Lie algebras of finite and affine type. It states that if $$uin U(mathfrak{g})$$ (the enveloping algebra of a Kac-Moody algebra) and $$Vinmathcal{O}$$ (the category O). Then $$Omega$$ (the generalised Casimir operator) and multiplication by $$u$$ commutes.

It is suffient to show that $$Omega$$ commutes with $$e_i$$ and $$f_i$$ (it’s clear for $$h$$). The proofs for $$e_i$$ and $$f_i$$ are very similar to let’s only concentrate on $$e_i$$.

He stars by calculating

begin{align} (sum_j f_alpha^{(j)}e_alpha^{(j)},e_i) &= sum_j(f_alpha^{(j)},e_i)e_alpha^{(j)} + sum_jf_alpha^{(j)}(e_alpha^{(j)},e_i) \ &= sum_j(f_alpha^{(j)},e_i)e_alpha^{(j)} – sum_jf_alpha^{(j)}(e_i,e_alpha^{(j)}) \ &= sum_j(f_alpha^{(j)},e_i)e_alpha^{(j)} – sum_j(f_alpha^{(j)},e_i)e_alpha^{(j)} \ &= sum_j(f_alpha^{(j)},e_i)e_alpha^{(j)} – sum_j(f_{alpha+alpha_i},e_i)e_{alpha+alpha_i}^{(j)} end{align}
Where if $$alpha+alpha_inotinPhi$$ then the second term is interpreted as $$0$$.

Hence my first two questions:

1. How do he get the first equality? Is it because we are in $$U(mathfrak{g})$$ and should think of $$f_alpha^{(j)}e_alpha^{(j)}$$ as $$(f_alpha^{(j)},e_alpha^{(j)})$$ so it’s just the Jacobi-identity?
2. Why can we replace $$alpha$$ with $${alpha+alpha_i}$$ in the last equiality?

We move on, then
$$(sum_{alphainPhi^+,alphaneqalpha_i}sum_j f_alpha^{(j)}e_alpha^{(j)},e_i)=sum_{alphainPhi^+,alphaneqalpha_i}sum_j(f_alpha^{(j)},e_i)e_alpha^{(j)} – sum_{alphainPhi^+,alphaneqalpha_i}sum_j(f_{alpha+alpha_i},e_i)e_{alpha+alpha_i}^{(j)}$$
It’s then stated that if $$alpha-alpha_inotinPhi$$ then $$(sum_jf_alpha^{(j)},e_i)=0$$ so we asume $$alpha=beta+alpha_i$$ and get
$$sum_{betainPhi^+,betaneqalpha_i}sum_j(f_{beta+alpha_i}^{(j)},e_i)e_{beta+alpha_i}^{(j)} – sum_{alphainPhi^+,alphaneqalpha_i}sum_j(f_{alpha+alpha_i},e_i)e_{alpha+alpha_i}^{(j)}=0$$
This yields my next question

1. He says if $$alpha-alpha_inotinPhi$$ then $$(sum_jf_alpha^{(j)},e_i)=0$$. But why’s that so? Also shouldn’t we justify that the second term is zero before we may write $$alpha=beta+alpha_i$$? Or does $$alpha+alpha_inotinPhi$$ when $$alpha-alpha_inotinPhi$$?
2. Why does the last equation give $$0$$?

Finally he states that since $$Omega=sum_jh_j’h_j”+2h_rho’+2sum_{alphainPhi^+}sum_jf_alpha^{(j)}e_alpha^{(j)}$$ then it actually suffices to show $$sum_jh_j’h_j”+2h_rho’+2f_ie_i$$ commutes with $$e_i$$ giving my final question.

1. Why is that sufficient? Haven’t we just shown $$e_i$$ commutes with $$sum_{alphainPhi^+}sum_jf_alpha^{(j)}e_alpha^{(j)}$$? Ie. why do we need the term $$2f_ie_i$$? Wouldn’t it be enough with $$sum_jh_j’h_j”+2h_rho’$$?

## real analysis – A question on a Hilbert – Schmidt operator.

Good evening, I have the following problem: let $$alpha>0$$ and $$T_alpha$$ the operator on the Hilbert space $$L^2((0,1))$$ $$T_alpha f(x):=int_0^{x^alpha}f(y)dy$$ for all $$fin L^2((0,1))$$. $$T_alpha$$ is clearly a Hilbert-Schmidt operator whose kernel is given by $$K(x,y):=chi_{(0,x^alpha)}(y)$$ (the characteristic function on $$(0,x^alpha)$$). It can be proved that $$T_alpha^n$$ is still a Hilbert-Schmidt integral operator for all $$ngeq1$$, whose Kernel $$K_n$$ satisfies $$K_{n+1}(x,y)=int_{(0,1)}K(x,w)K_n(w,y)dw$$ for all $$ngeq1$$. I must prove that $$0leq K_n(x,y)leq c_nchi_{(0,x^{alpha^n})}(y)x^{s_n(alpha)}$$ for all $$x,yin(0,1)$$, where $$s_n(alpha)=frac{alpha-alpha^n}{1-alpha}$$ (with $$s_n(1)=n-1$$) and constants $$c_n$$ which satisfy the relation $$c_1=1$$ and $$c_n=frac{1-alpha}{1-alpha^n}c_n$$ $$forall ngeq1$$ (with $$c_{n+1}=frac{1}{n}c_n$$).

I tried to use the recursive relation. The fact that $$K_n(x,y)geq0$$ is obvious by induction. Then, the assertion is clearly obvious in the case $$n=1$$. So, I tried to use an induction procedure for the second inequality too. For, I deduced that
$$begin{equation} begin{split} K_{n+1}(x,y)&leqint_{(0,1)}chi_{(0,x^alpha)}(w)c_nchi_{(0,w^alpha)}(y)w^{s_n(alpha)}dw=c_nint_{(0,1)}chi_{(0,x^alpha)}(w)chi_{(y^{1/alpha^n},1)}(w)w^{s_n(alpha)}dw=\ &=c_nint_{(0,1)}chi_{(0,x^alpha)cap(y^{1/alpha^n},1)}(w)w^{s_n(alpha)}dw. end{split} end{equation}$$

So I divided the two cases: $$x^alpha ($$y>x^{alpha^{n+1}}$$), in the which case the intersection is empty and $$K_n(x,y)=0$$. In the other case, (since all the variables lie in $$(0,1)$$, it must be $$0leq y^{1/alpha^n}leq x^{alpha}leq1$$) it is
$$begin{equation} begin{split} K_{n+1}(x,y)&leq c_nint_{y^{1/alpha^n}}^{x^alpha}w^{s_n(alpha)}dw=c_nfrac{w^{s_n(alpha)+1}}{s_n(alpha)+1}Big|_{y^{1/alpha^n}}^{x^alpha}. end{split} end{equation}$$
Therefore, $$K_{n+1}(x,y)leq c_nleft(frac{x^{alpha(s_n(alpha)+1)}}{s_n(alpha)+1}-frac{y^{(s_(alpha)+1)/alpha^n}}{s_n(alpha)+1}right)chi_{(0,x^{alpha^{n+1}})}(y)$$. This is the point where I get stuck.

## c# – Sobel Operator – SIMD x86 Intrinsics Implementation

I’m learning C# .NET 5 Intrinsics and interested in best practices. It’s really hard now to find enough information about how SIMD instructions (logically/internally) work in .NET. In addition i’m not familiar with C++ and Assebmly languages.

The purpose of the solution – apply Sobel Operator filter to the loaded image. For image operations i used `System.Drawing.Common` NuGet package. Thus the solution is Windows-only.

The `SobelOperator` class contains two Sobel Operator implementations:

1. `SobelOperatorScalar` – Scalar solution that can be used as a fallback if current CPU is not compartible with AVX2.
2. `SobelOperatorSimd` – SIMD x86 solution for hardware acceleration. – review target

### Code for review

``````public interface ISobelOperator
{
Bitmap Apply(Bitmap bmp);
}

public class SobelOperator : ISobelOperator
{
private static Color() _grayPallette;

public bool IsHardwareAccelerated { get; }

public SobelOperator(bool hardwareAccelerated = true)
{
if (_grayPallette == null)
_grayPallette = Enumerable.Range(0, 256).Select(i => Color.FromArgb(i, i, i)).ToArray();

IsHardwareAccelerated = hardwareAccelerated && Avx2.IsSupported;

_operator = IsHardwareAccelerated ? new SobelOperatorSimd() : new SobelOperatorScalar();
}

public Bitmap Apply(Bitmap bmp)
=> _operator.Apply(bmp);

private class SobelOperatorSimd : ISobelOperator
{
private const byte m0 = 0b01001001;
private const byte m1 = 0b10010010;
private const byte m2 = 0b00100100;

//0.299R + 0.587G + 0.114B
private readonly Vector256<float> bWeight = Vector256.Create(0.114f);
private readonly Vector256<float> gWeight = Vector256.Create(0.587f);
private readonly Vector256<float> rWeight = Vector256.Create(0.299f);
private readonly Vector256<int> bMut = Vector256.Create(0, 3, 6, 1, 4, 7, 2, 5);
private readonly Vector256<int> gMut = Vector256.Create(1, 4, 7, 2, 5, 0, 3, 6);
private readonly Vector256<int> rMut = Vector256.Create(2, 5, 0, 3, 6, 1, 4, 7);

(MethodImpl(MethodImplOptions.AggressiveInlining))
private unsafe Vector256<int> GetBrightness(byte* ptr)
{
Vector256<int> v0 = Avx2.ConvertToVector256Int32(ptr);
Vector256<int> v1 = Avx2.ConvertToVector256Int32(ptr + 8);
Vector256<int> v2 = Avx2.ConvertToVector256Int32(ptr + 16);

Vector256<int> vb = Avx2.Blend(Avx2.Blend(v0, v1, m1), v2, m2);
vb = Avx2.PermuteVar8x32(vb, bMut);
Vector256<int> vg = Avx2.Blend(Avx2.Blend(v0, v1, m2), v2, m0);
vg = Avx2.PermuteVar8x32(vg, gMut);
Vector256<int> vr = Avx2.Blend(Avx2.Blend(v0, v1, m0), v2, m1);
vr = Avx2.PermuteVar8x32(vr, rMut);
Vector256<float> vfb = Avx.Multiply(Avx.ConvertToVector256Single(vb), bWeight);
Vector256<float> vfg = Avx.Multiply(Avx.ConvertToVector256Single(vg), gWeight);
Vector256<float> vfr = Avx.Multiply(Avx.ConvertToVector256Single(vr), rWeight);
}

(MethodImpl(MethodImplOptions.AggressiveInlining))
private unsafe void ToGrayscale(byte* srcPtr, byte* dstPtr, int pixelsCount)
{
byte* tail = srcPtr + (pixelsCount & -16) * 3;
byte* srcEnd = srcPtr + pixelsCount * 3;
byte* dstEnd = dstPtr + pixelsCount;

while (true)
{
while (srcPtr < tail)
{
Vector256<int> vi0 = GetBrightness(srcPtr);
Vector256<int> vi1 = GetBrightness(srcPtr + 24);
Vector128<short> v0 = Sse2.PackSignedSaturate(Avx2.ExtractVector128(vi0, 0), Avx2.ExtractVector128(vi0, 1));
Vector128<short> v1 = Sse2.PackSignedSaturate(Avx2.ExtractVector128(vi1, 0), Avx2.ExtractVector128(vi1, 1));
Sse2.Store(dstPtr, Sse2.PackUnsignedSaturate(v0, v1));
srcPtr += 48;
dstPtr += 16;
}
if (srcPtr == srcEnd)
break;
tail = srcEnd;
srcPtr = srcEnd - 48;
dstPtr = dstEnd - 16;
}
}

(MethodImpl(MethodImplOptions.AggressiveInlining))
private static unsafe Vector128<byte> ApplySobelKernel(byte* srcPtr, int width)
{
Vector256<short> v00 = Avx2.ConvertToVector256Int16(srcPtr);
Vector256<short> v01 = Avx2.ConvertToVector256Int16(srcPtr + 1);
Vector256<short> v02 = Avx2.ConvertToVector256Int16(srcPtr + 2);
Vector256<short> v10 = Avx2.ConvertToVector256Int16(srcPtr + width);
Vector256<short> v12 = Avx2.ConvertToVector256Int16(srcPtr + width + 2);
Vector256<short> v20 = Avx2.ConvertToVector256Int16(srcPtr + width * 2);
Vector256<short> v21 = Avx2.ConvertToVector256Int16(srcPtr + width * 2 + 1);
Vector256<short> v22 = Avx2.ConvertToVector256Int16(srcPtr + width * 2 + 2);

Vector256<short> vgx = Avx2.Subtract(v02, v00);
vgx = Avx2.Subtract(vgx, Avx2.ShiftLeftLogical(v10, 1));
vgx = Avx2.Subtract(vgx, v20);

Vector256<short> vgy = Avx2.Add(v00, Avx2.ShiftLeftLogical(v01, 1));
vgy = Avx2.Subtract(vgy, v20);
vgy = Avx2.Subtract(vgy, Avx2.ShiftLeftLogical(v21, 1));
vgy = Avx2.Subtract(vgy, v22);

// sqrt(vgx * vgx + vgy * vgy)
Vector256<short> vgp0 = Avx2.UnpackLow(vgx, vgy);
Vector256<short> vgp1 = Avx2.UnpackHigh(vgx, vgy);
Vector256<int> gt0 = Avx.ConvertToVector256Int32WithTruncation(Avx.Sqrt(Avx.ConvertToVector256Single(v0)));
Vector256<int> gt1 = Avx.ConvertToVector256Int32WithTruncation(Avx.Sqrt(Avx.ConvertToVector256Single(v1)));

Vector128<short> gts0 = Sse2.PackSignedSaturate(Avx2.ExtractVector128(gt0, 0), Avx2.ExtractVector128(gt1, 0));
Vector128<short> gts1 = Sse2.PackSignedSaturate(Avx2.ExtractVector128(gt0, 1), Avx2.ExtractVector128(gt1, 1));
return Sse2.PackUnsignedSaturate(gts0, gts1);
}

public Bitmap Apply(Bitmap bmp)
{
int width = bmp.Width;
int height = bmp.Height;
int pixelsCount = width * height;
byte() buffer = new byte(pixelsCount);

Rectangle rect = new Rectangle(Point.Empty, bmp.Size);
Bitmap outBmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
ColorPalette pal = outBmp.Palette;
for (int i = 0; i < 256; i++)
pal.Entries(i) = _grayPallette(i);
outBmp.Palette = pal;

unsafe
{
fixed (byte* bufPtr = buffer)
{
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
ToGrayscale((byte*)bmpData.Scan0.ToPointer(), bufPtr, pixelsCount);
bmp.UnlockBits(bmpData);

BitmapData outBmpData = outBmp.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
byte* dstPtr = (byte*)outBmpData.Scan0.ToPointer();

int length = pixelsCount - width * 2 - 1;
byte* tail = bufPtr + (length & -16);
byte* srcPos = bufPtr;
byte* srcEnd = bufPtr + length;
byte* dstPos = dstPtr + width + 1;
byte* dstEnd = dstPos + length;

while (true)
{
while (srcPos < tail)
{
Sse2.Store(dstPos, ApplySobelKernel(srcPos, width));
srcPos += 16;
dstPos += 16;
}

if (srcPos == srcEnd)
break;
tail = srcEnd;
srcPos = srcEnd - 16;
dstPos = dstEnd - 16;
}

for (dstPos = dstPtr + width; dstPos <= dstPtr + pixelsCount - width; dstPos += width)
{
*dstPos-- = 0;
*dstPos++ = 0;
}

outBmp.UnlockBits(outBmpData);
}
}

return outBmp;
}
}

private class SobelOperatorScalar : ISobelOperator
{
public Bitmap Apply(Bitmap bmp)
{
BitmapData bmpData = bmp.LockBits(new Rectangle(Point.Empty, bmp.Size), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
int strideLength = bmpData.Stride * bmpData.Height;
byte() buffer = new byte(Math.Abs(strideLength));
Marshal.Copy(bmpData.Scan0, buffer, 0, strideLength);
bmp.UnlockBits(bmpData);

int width = bmp.Width;
int height = bmp.Height;
int pixelsCount = width * height;
byte() pixelBuffer = new byte(pixelsCount);
byte() resultBuffer = new byte(pixelsCount);

//0.299R + 0.587G + 0.114B
for (int i = 0; i < pixelsCount; i++)
{
int offset = i * 3;
byte brightness = (byte)(buffer(offset) * 0.114f + buffer(offset + 1) * 0.587f + buffer(offset + 2) * 0.299f);
pixelBuffer(i) = brightness;
}

for (int i = width + 1; i < pixelsCount - width - 1; i++)
{
if (i % width == width - 1)
i += 2;

int gx = -pixelBuffer(i - 1 - width) + pixelBuffer(i + 1 - width) - 2 * pixelBuffer(i - 1) +
2 * pixelBuffer(i + 1) - pixelBuffer(i - 1 + width) + pixelBuffer(i + 1 + width);

int gy = pixelBuffer(i - 1 - width) + 2 * pixelBuffer(i - width) + pixelBuffer(i + 1 - width) -
pixelBuffer(i - 1 + width) - 2 * pixelBuffer(i + width) - pixelBuffer(i + 1 + width);

int gt = (int)MathF.Sqrt(gx * gx + gy * gy);
if (gt > byte.MaxValue) gt = byte.MaxValue;

resultBuffer(i) = (byte)gt;
}

Bitmap outBmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
BitmapData outBmpData = outBmp.LockBits(new Rectangle(Point.Empty, outBmp.Size), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
Marshal.Copy(resultBuffer, 0, outBmpData.Scan0, outBmpData.Stride * outBmpData.Height);
outBmp.UnlockBits(outBmpData);
ColorPalette pal = outBmp.Palette;
for (int i = 0; i < 256; i++)
pal.Entries(i) = _grayPallette(i);
outBmp.Palette = pal;
return outBmp;
}
}
}
``````

### Output test

Test image

Program.cs

``````static void Main(string() args)
{
const string fileName = "image.jpg";
Bitmap bmp = new Bitmap(fileName);

SobelOperator sobelOperator = new SobelOperator();
Console.WriteLine(\$"SIMD accelerated: {(sobelOperator.IsHardwareAccelerated ? "Yes" : "No")}");
Bitmap result = sobelOperator.Apply(bmp);
result.Save("out.jpg", ImageFormat.Jpeg);

Console.WriteLine("Done.");
}
``````

Console output

``````SIMD accelerated: Yes
Done.
``````

Output Image

Output images of Scalar and SIMD implementations are binary idential.

### Benchmark.NET

``````(MemoryDiagnoser)
public class MyBenchmark
{
private readonly ISobelOperator _sobelOperator = new SobelOperator();
private readonly ISobelOperator _sobelOperatorSw = new SobelOperator(false);
private readonly Bitmap bmp = new Bitmap(@"C:Sourceimage.jpg");

(Benchmark(Description = "SIMD Enabled"))
public Bitmap TestSimd()
{
return _sobelOperator.Apply(bmp);
}

(Benchmark(Description = "SIMD Disabled"))
public Bitmap TestScalar()
{
return _sobelOperatorSw.Apply(bmp);
}
}

static void Main(string() args)
{
var summary = BenchmarkRunner.Run<MyBenchmark>();
}
``````
``````BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042
Intel Core i7-4700HQ CPU 2.40GHz (Haswell), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=5.0.101
(Host)     : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT
DefaultJob : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT

|          Method |      Mean |     Error |    StdDev |    Gen 0 |    Gen 1 |    Gen 2 | Allocated |
|---------------- |----------:|----------:|----------:|---------:|---------:|---------:|----------:|
|  'SIMD Enabled' |  7.285 ms | 0.1165 ms | 0.1089 ms | 992.1875 | 992.1875 | 992.1875 |   3.35 MB |
| 'SIMD Disabled' | 48.412 ms | 0.2312 ms | 0.2162 ms | 454.5455 | 454.5455 | 454.5455 |  16.61 MB |
``````

Intrinsics solution is ~6.6x Times faster. And eating less memory in general because it’s `unsafe` and doesn’t use `Marshal.Copy` to load/save the `byte()` buffers.

## intuition – Intuitive explanation why “shadow operator” \$frac D{e^D-1}\$ connects logarithms with trigonometric functions?

Consider the operator $$frac D{e^D-1}$$ which we will call “shadow”:

$$frac D{e^D-1}f(x)=frac1{2 pi }int_{-infty }^{+infty } frac{e^{-iwx}}{e^{-i w}-1}int_{-infty }^{+infty } e^{i t w} f'(t) , dt , dw$$

The integrals here should be understood as Fourier transforms.

Now, intuitively, why the following?

$$frac D{e^D-1} left(frac1piln left(frac{x+1/2 +frac{x}{pi }}{x+1/2 -frac{x}{pi }}right)right)=tan x$$

There are other examples where shadow converts trigonometric functions into inverse trigonometric, logarithms to exponents, etc:

$$frac D{e^D-1} left(frac1{pi }ln left(frac{x+1/2-frac{x}{pi }}{x-1/2+frac{x}{pi }}right)right)=cot x$$

## Avoid the object/array check and treat the return value the same way with JavaScript spread operator?

I’m trying to implement a function (a template-helper function) which provides a simple merge-like functionality for both arrays and objects. The two functions are basically looks identical:

``````const mergeArrays = (first, ...rest) =>
rest.reduce((acc, curr) => (( ...acc, ...curr)), first);

const mergeObjects = (first, ...rest) =>
rest.reduce((acc, curr) => ({ ...acc, ...curr }), first);
``````

One could do a type check and a local variable to write a single function like this:

``````const mergeArraysOrObjects1 = (first, ...rest) => {
let reducer = null;
if ('object' === typeof first && null !== first) {
reducer = (acc, curr) => ({ ...acc, ...curr });
}
if (Array.isArray(first)) {
reducer = (acc, curr) => (...acc, ...curr);
}

if (!reducer) {
throw new Error('The "merge" filter only works with arrays and hashes.');
}

return rest.reduce(reducer, first);
}
``````

… but it seems so ugly to me. Another possibility is a type check and inline conditional:

``````const mergeArraysOrObjects2 = (first, ...rest) => {
if ('object' !== typeof first || null === first) {
throw new Error('The "merge" filter only works with arrays and hashes.');
}

return rest.reduce(
(acc, curr) => Array.isArray(acc) ? (...acc, ...curr) : {...acc, ...curr},
first
);
}
``````

I’m still learning JavaScript so I’m guessing if there is a more elegant and concise way to treat the return value the same way.