Hi,all
Zeta(z)=1/1^z+1/2^z+1/3^z+...+1/n^z+...
n: All natural numbers
z = a+bi, a != 1
Zeta(z) trivial zeros: a = -2,-4,-6,...,-2n
Zeta(z) Nontrivial zeros: a = 1/2, b = ?(40%) [There isn't still strict proof now]
The Zeta(z) Nontrivial zeros are related to the count of prime numbers.
I drawed the Zeta(z) curve. but it is strange. Do you know how to draw the following left image?
I havent a clue, but it looks very similar in some aspects to a cardioid polar pattern (https://www.lewitt-audio.com/blog/cardioid-polar-pattern), at least the outermost curves.. except for the orientation.
(https://i.postimg.cc/fWS6vmwY/polar-pattern-03-transp-0.png)
Probably doesn't help you at all, but it was the first thing that came to mind when I saw your image on the left.
Try this (press R to reset animation). You can also save the generated image
Links below holds the full source (and solution database for VS2022)
https://www.mediafire.com/file/t4bxo1lgvc2bdm8/Zeta10.rar/file (https://www.mediafire.com/file/t4bxo1lgvc2bdm8/Zeta10.rar/file)
https://www.mediafire.com/file/2axp5fyma44y6on/Zeta11.zip/file (https://www.mediafire.com/file/2axp5fyma44y6on/Zeta11.zip/file)
(https://i.postimg.cc/xN3t1HHw/Clipboard-05-09-2025-01.png) (https://postimg.cc/xN3t1HHw)
// ZetaVisualizerFinal.c - Extended coordinate labels to match grid lines
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>
#include <math.h>
#include <stdio.h>
#include <time.h>
#include <commdlg.h>
#pragma comment(lib, "gdiplus.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")
using namespace Gdiplus;
// Global variables for animation
static float animationProgress = 0.0f; // 0.0 to 1.0
static const float ANIMATION_SPEED = 0.005f; // Adjust for faster/slower animation
static const UINT_PTR ANIMATION_TIMER_ID = 1;
static bool isAnimationRunning = false; // Track animation state
// Complex number structure
typedef struct {
double real;
double imag;
} Complex;
// Improved Zeta function with better convergence
Complex Zeta(Complex s, int iterations) {
Complex result = { 0.0, 0.0 };
double running_sum = 0.0;
// Standard Dirichlet series for first N terms
for (int n = 1; n <= iterations; n++) {
double term = 1.0 / pow(n, s.real);
double angle = -s.imag * log(n);
result.real += term * cos(angle);
result.imag += term * sin(angle);
if (n > 10 && fabs(result.real - running_sum) < 1e-10) {
break;
}
running_sum = result.real;
}
// Add a simple Euler-Maclaurin correction for remainder
if (iterations > 10) {
int N = iterations;
double term = 1.0 / pow(N + 1, s.real);
double angle = -s.imag * log(N + 1);
// Approximate remainder: integral term ~ 1/(s-1) * N^(1-s)
double correction_real = term * cos(angle) / (s.real - 1.0);
double correction_imag = term * sin(angle) / (s.real - 1.0);
result.real += correction_real;
result.imag += correction_imag;
}
return result;
}
// Draw the enhanced Zeta function visualization
void DrawEnhancedZeta(HDC hdc, int width, int height, float progress) {
Graphics graphics(hdc);
graphics.SetSmoothingMode(SmoothingModeAntiAlias);
graphics.SetCompositingQuality(CompositingQualityHighQuality);
graphics.SetTextRenderingHint(TextRenderingHintAntiAlias); // Improve text rendering
// Dark gradient background
LinearGradientBrush background(
Point(0, 0),
Point(width, height),
Color(255, 10, 20, 50), // Deep blue
Color(255, 0, 0, 0)); // Black
graphics.FillRectangle(&background, 0, 0, width, height);
// Set up coordinate system
REAL centerX = width / 2.0f;
REAL centerY = height / 2.0f;
REAL scale = (REAL)min(width, height) / 4.0f;
REAL unitScale = scale / 6.0f; // Pixels per unit (zeta.real or zeta.imag)
// Draw subtle grid lines
Pen gridPen(Color(50, 100, 100, 150), 0.3f);
for (int i = -6; i <= 6; i++) {
graphics.DrawLine(&gridPen,
0.0f, centerY + i * scale / 3.0f,
(REAL)width, centerY + i * scale / 3.0f);
graphics.DrawLine(&gridPen,
centerX + i * scale / 3.0f, 0.0f,
centerX + i * scale / 3.0f, (REAL)height);
}
// Draw glowing axes
LinearGradientBrush axisBrush(
Point(0, (int)centerY),
Point(width, (int)centerY),
Color(150, 200, 200, 255),
Color(50, 100, 100, 100));
Pen axisPen(&axisBrush, 1.8f);
graphics.DrawLine(&axisPen, 0.0f, centerY, (REAL)width, centerY);
graphics.DrawLine(&axisPen, centerX, 0.0f, centerX, (REAL)height);
// Draw critical line
LinearGradientBrush criticalBrush(
Point((int)centerX, 0),
Point((int)centerX, height),
Color(150, 255, 150, 50),
Color(50, 100, 255, 50));
Pen criticalPen(&criticalBrush, 2.0f);
REAL criticalX = centerX + scale * 0.5f;
graphics.DrawLine(&criticalPen, criticalX, 0.0f, criticalX, (REAL)height);
// Draw Zeta function curve with animation
const int iterations = 200;
const double t_start = 0.0;
const double t_end = 30.0;
const double t_step = 0.02;
double t_max = t_start + progress * (t_end - t_start); // Animate up to t_max
GraphicsPath path;
PointF prevPoint;
bool firstPoint = true;
for (double t = t_start; t <= t_max; t += t_step) {
Complex s = { 0.5, t };
Complex zeta = Zeta(s, iterations);
REAL x = centerX + (REAL)zeta.imag * scale / 6.0f;
REAL y = centerY - (REAL)zeta.real * scale / 6.0f;
if (!firstPoint) {
path.AddLine(prevPoint, PointF(x, y));
}
else {
path.StartFigure();
firstPoint = false;
}
prevPoint = PointF(x, y);
}
// Neon gradient for Zeta curve
Color colors[] = {
Color(200, 255, 50, 50),
Color(200, 255, 165, 0),
Color(200, 255, 0, 255),
Color(200, 50, 50, 255)
};
REAL positions[] = { 0.0f, 0.33f, 0.67f, 1.0f };
LinearGradientBrush pathBrush(
Point(0, (int)(centerY - scale)),
Point(0, (int)(centerY + scale)),
Color(255, 255, 255, 255),
Color(255, 255, 255, 255));
pathBrush.SetInterpolationColors(colors, positions, 4);
// Draw glow and main curve
Pen glowPen(&pathBrush, 5.0f);
glowPen.SetColor(Color(100, 255, 255, 255));
graphics.DrawPath(&glowPen, &path);
Pen zetaPen(&pathBrush, 2.5f);
graphics.DrawPath(&zetaPen, &path);
// Add annotations with adjusted positions
Font font(L"Cambria Math", 16, FontStyleBold);
Font smallFont(L"Cambria Math", 12, FontStyleRegular); // Smaller font for coordinate labels
SolidBrush shadowBrush(Color(80, 0, 0, 0));
SolidBrush textBrush(Color(255, 230, 230, 230));
StringFormat format;
format.SetAlignment(StringAlignmentCenter);
// Title: "ζ(s) where s = ½ + ti" (top center)
Font bigFont(L"Cambria Math", 20, FontStyleBold);
graphics.DrawString(L"ζ(s) where s = ½ + ti", -1, &bigFont,
PointF(centerX + 4.0f, 24.0f), &format, &shadowBrush);
graphics.DrawString(L"ζ(s) where s = ½ + ti", -1, &bigFont,
PointF(centerX, 20.0f), &format, &textBrush);
// Critical line label: "Re(s) = ½" (right side, near critical line)
graphics.DrawString(L"Re(s) = ½", -1, &font,
PointF(criticalX + 4.0f, 60.0f), &format, &shadowBrush);
graphics.DrawString(L"Re(s) = ½", -1, &font,
PointF(criticalX, 56.0f), &format, &textBrush);
// Axis label: "Im(ζ(s))" (right side)
REAL imLabelX = (REAL)width - 100.0f;
graphics.DrawString(L"Im(ζ(s))", -1, &font,
PointF(imLabelX + 4.0f, centerY - 24.0f), &shadowBrush);
graphics.DrawString(L"Im(ζ(s))", -1, &font,
PointF(imLabelX, centerY - 20.0f), &textBrush);
// Axis label: "Re(ζ(s))" (bottom center)
graphics.DrawString(L"Re(ζ(s))", -1, &font,
PointF(centerX + 14.0f, (REAL)height - 44.0f), &shadowBrush);
graphics.DrawString(L"Re(ζ(s))", -1, &font,
PointF(centerX + 10.0f, (REAL)height - 40.0f), &textBrush);
// Add coordinate labels for horizontal axis (Im(ζ(s))): -12 to 12, step 2
for (int i = -6; i <= 6; i++) {
int value = i * 2; // Grid lines are at intervals of 2 units
REAL xPos = centerX + value * unitScale;
WCHAR label[16];
swprintf(label, 16, L"%d", value);
graphics.DrawString(label, -1, &smallFont,
PointF(xPos + 2.0f, centerY + 16.0f), &format, &shadowBrush);
graphics.DrawString(label, -1, &smallFont,
PointF(xPos, centerY + 12.0f), &format, &textBrush);
}
// Add coordinate labels for vertical axis (Re(ζ(s))): -12 to 12, step 2
StringFormat nearFormat;
nearFormat.SetAlignment(StringAlignmentNear); // Left-align for vertical labels
for (int i = -6; i <= 6; i++) {
int value = i * 2; // Grid lines are at intervals of 2 units
REAL yPos = centerY - value * unitScale; // Negative because screen y increases downward
WCHAR label[16];
if (value == 0) {
swprintf(label, 16, L"0");
}
else {
swprintf(label, 16, L"%di", value);
}
graphics.DrawString(label, -1, &smallFont,
PointF(centerX - 30.0f + 2.0f, yPos + 2.0f), &nearFormat, &shadowBrush);
graphics.DrawString(label, -1, &smallFont,
PointF(centerX - 30.0f, yPos), &nearFormat, &textBrush);
}
// Add animated non-trivial zero markers
double zeros[] = { 14.1347, 21.0220, 25.0109, 30.4249 }; // Known zeros
int numZeros = sizeof(zeros) / sizeof(zeros[0]);
for (int i = 0; i < numZeros; i++) {
if (zeros[i] <= t_max) { // Only draw zeros up to current progress
Complex s = { 0.5, zeros[i] };
Complex zeta = Zeta(s, iterations);
REAL x = centerX + (REAL)zeta.imag * scale / 6.0f;
REAL y = centerY - (REAL)zeta.real * scale / 6.0f;
LinearGradientBrush zeroBrush(
Point((int)(x - 10.0f), (int)(y - 10.0f)),
Point((int)(x + 10.0f), (int)(y + 10.0f)),
Color(200, 255, 100, 100),
Color(0, 255, 255, 255));
graphics.FillEllipse(&zeroBrush, x - 7.0f, y - 7.0f, 14.0f, 14.0f);
Pen zeroPen(Color(150, 255, 255, 255), 1.0f);
graphics.DrawEllipse(&zeroPen, x - 7.0f, y - 7.0f, 14.0f, 14.0f);
}
}
}
// Helper function to get PNG encoder CLSID
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) {
UINT num = 0, size = 0;
Gdiplus::GetImageEncodersSize(&num, &size);
if (size == 0) return -1;
ImageCodecInfo* pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
Gdiplus::GetImageEncoders(num, size, pImageCodecInfo);
for (UINT j = 0; j < num; ++j) {
if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0) {
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j;
}
}
free(pImageCodecInfo);
return -1;
}
// Save visualization as PNG
void SaveAsPng(HWND hWnd, int width, int height, const WCHAR* filename) {
// Create a bitmap
Bitmap bitmap(width, height, PixelFormat32bppARGB);
Graphics bitmapGraphics(&bitmap);
bitmapGraphics.SetSmoothingMode(SmoothingModeAntiAlias);
bitmapGraphics.SetCompositingQuality(CompositingQualityHighQuality);
bitmapGraphics.SetTextRenderingHint(TextRenderingHintAntiAlias);
// Draw the full visualization (progress = 1.0)
HDC hdc = bitmapGraphics.GetHDC();
DrawEnhancedZeta(hdc, width, height, 1.0f);
bitmapGraphics.ReleaseHDC(hdc);
// Save as PNG
CLSID clsid;
if (GetEncoderClsid(L"image/png", &clsid) != -1) {
bitmap.Save(filename, &clsid, NULL);
char msg[512];
snprintf(msg, sizeof(msg), "Visualization saved as %S", filename);
MessageBoxA(hWnd, msg, "Success", MB_OK | MB_ICONINFORMATION);
}
else {
MessageBoxA(hWnd, "Failed to save PNG: PNG encoder not found", "Error", MB_OK | MB_ICONERROR);
}
}
// Open file dialog for saving PNG
void ShowSaveDialog(HWND hWnd, int width, int height) {
WCHAR filename[MAX_PATH] = L"ZetaVisualization.png";
OPENFILENAMEW ofn = { 0 };
ofn.lStructSize = sizeof(OPENFILENAMEW);
ofn.hwndOwner = hWnd;
ofn.lpstrFilter = L"PNG Files (*.png)\0*.png\0All Files (*.*)\0*.*\0";
ofn.lpstrFile = filename;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrDefExt = L"png";
ofn.Flags = OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
if (GetSaveFileNameW(&ofn)) {
SaveAsPng(hWnd, width, height, filename);
}
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
static int width, height;
switch (message) {
case WM_CREATE:
// Animation starts paused; no timer set initially
break;
case WM_TIMER:
if (wParam == ANIMATION_TIMER_ID) {
animationProgress += ANIMATION_SPEED;
if (animationProgress > 1.0f) {
animationProgress = 1.0f; // Stop at full progress
KillTimer(hWnd, ANIMATION_TIMER_ID);
isAnimationRunning = false;
}
InvalidateRect(hWnd, NULL, FALSE); // FALSE to avoid background erase
}
break;
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
RECT rect;
GetClientRect(hWnd, &rect);
width = rect.right;
height = rect.bottom;
// Create double buffer
HDC memDC = CreateCompatibleDC(hdc);
HBITMAP memBitmap = CreateCompatibleBitmap(hdc, width, height);
HBITMAP oldBitmap = (HBITMAP)SelectObject(memDC, memBitmap);
// Fill background to avoid artifacts
HBRUSH blackBrush = (HBRUSH)GetStockObject(BLACK_BRUSH);
FillRect(memDC, &rect, blackBrush);
// Draw to memory DC
DrawEnhancedZeta(memDC, width, height, animationProgress);
// Copy to screen
BitBlt(hdc, 0, 0, width, height, memDC, 0, 0, SRCCOPY);
// Clean up
SelectObject(memDC, oldBitmap);
DeleteObject(memBitmap);
DeleteDC(memDC);
EndPaint(hWnd, &ps);
break;
}
case WM_SIZE:
width = LOWORD(lParam);
height = HIWORD(lParam);
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case 1001: // Save As
ShowSaveDialog(hWnd, width, height);
break;
case 1002: // Start Animation
if (!isAnimationRunning) {
SetTimer(hWnd, ANIMATION_TIMER_ID, 16, NULL); // ~60 FPS
isAnimationRunning = true;
}
break;
case 1003: // Pause Animation
if (isAnimationRunning) {
KillTimer(hWnd, ANIMATION_TIMER_ID);
isAnimationRunning = false;
}
break;
}
break;
case WM_KEYDOWN:
if (wParam == 'R') { // Reset animation
animationProgress = 0.0f;
if (!isAnimationRunning) {
SetTimer(hWnd, ANIMATION_TIMER_ID, 16, NULL);
isAnimationRunning = true;
}
InvalidateRect(hWnd, NULL, FALSE);
}
break;
case WM_DESTROY:
if (isAnimationRunning) {
KillTimer(hWnd, ANIMATION_TIMER_ID);
}
PostQuitMessage(0);
break;
default:
return DefWindowProcA(hWnd, message, wParam, lParam);
}
return 0;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
// Create menu
HMENU hMenu = CreateMenu();
HMENU hFileMenu = CreatePopupMenu();
AppendMenuA(hFileMenu, MF_STRING, 1001, "Save As...");
AppendMenuA(hFileMenu, MF_STRING, 1002, "Start Animation");
AppendMenuA(hFileMenu, MF_STRING, 1003, "Pause Animation");
AppendMenuA(hMenu, MF_POPUP, (UINT_PTR)hFileMenu, "File");
WNDCLASSA wc = { 0 };
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = "ZetaVisualizer";
wc.hCursor = LoadCursorA(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
RegisterClassA(&wc);
HWND hWnd = CreateWindowA("ZetaVisualizer", "Riemann Zeta Function Visualizer",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
1200, 900, NULL, hMenu, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
MSG msg;
while (GetMessageA(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
DestroyMenu(hMenu);
GdiplusShutdown(gdiplusToken);
return (int)msg.wParam;
}
Attached the binary file. And on the links, the full source
hi guga
I did a zeta approximation in FreeBasic years ago using the following
' f(k)=(k+nc)^-n
' inf nc inf inf
' ==== ==== / ==== B
' \ 1 \ 1 [ \ (2*k) (2*k-1)
' > ----- = > ----- + I f(k) dk + B * f(0) - > ------ f (0)
' / n / n ] 1 / (2*k)!
' ==== k ==== k / ====
' k = 1 k = 1 0 k = 1
I posted the code here https://www.freebasic.net/forum/viewtopic.php?p=193860#p193860 (https://www.freebasic.net/forum/viewtopic.php?p=193860#p193860)
Quote from: jack on May 10, 2025, 01:27:48 AMhi guga
I did a zeta approximation in FreeBasic years ago using the following
' f(k)=(k+nc)^-n
' inf nc inf inf
' ==== ==== / ==== B
' \ 1 \ 1 [ \ (2*k) (2*k-1)
' > ----- = > ----- + I f(k) dk + B * f(0) - > ------ f (0)
' / n / n ] 1 / (2*k)!
' ==== k ==== k / ====
' k = 1 k = 1 0 k = 1
I can post the code if anyone is interested
Tks, Jack. It would be good to see the code. Maybe it can later be ported to masm or even plain C if needed
I edited my post with a link to the source
Quote from: jack on May 10, 2025, 01:36:15 AMI edited my post with a link to the source
Tks, try this. Grok ported your version.
https://www.mediafire.com/file/bpmn4b5pj74ka2m/Zeta12.rar/file (https://www.mediafire.com/file/bpmn4b5pj74ka2m/Zeta12.rar/file)
(https://i.postimg.cc/hfYzXH5P/Clipboard-05-09-2025-01.png) (https://postimg.cc/hfYzXH5P)
hey guga
Grok explained what the code does better than my comments in my code :biggrin:
Quote from: jack on May 10, 2025, 07:39:56 AMhey guga
Grok explained what the code does better than my comments in my code :biggrin:
Indeed :biggrin: Grok is a wonderful tool. I started 1st using deepseek to create some basic app that worked similar to the left image that six_L showed. But, the result was inaccurate. Nevertheless, i took the code generated on deepseek and used it through Grok (the x version and not the one from the site) to it fix the code and make it more similar to the image, enhancing graphics and focusing in using gdi+. It fixed and i started to play with it, adding animation, a menu etc. Then when you uploaded your freebasic version, since i already had the skeleton, i mainly asked Grok to adapt the code he just did in C to yours in freebasic.
Grok does a very good work in Plain C language, but still lack the same skill in what concerns assembly (no matter if for masm, rosasm, fasm or nasm). For assembly programming you must not trust 100% on the generated code, but use it mainly as a guidance to improve yours.
In any case, the results i´ve seen so far are good enough to save some time in development. Most likely, until the end of the year i believe Grok (and others) should be more advanced in what is related to assembly language to save us even more time for coding.
One thing interesting, i have no idea what is this zeta all about. I only realized what was that, after pasting the comments six_L did on deepseek and ask him to do an app based on this. The rest, was fine tunned with Grok.
I started on deepseek, simply inserting this:
QuotePls create me a function in plain C using Gdi+ on a way i can generate the graphic on this link (image on left)https://masm32.com/board/index.php?action=dlattach;attach=18375;image. The goal is: Hi,all
Zeta(z)=1/1^z+1/2^z+1/3^z+...+1/n^z+...
n: All natural numbers
z = a+bi, a != 1
Zeta(z) trivial zeros: a = -2,-4,-6,...,-2n
Zeta(z) Nontrivial zeros: a = 1/2, b = ?(40%) [There isn't still strict proof now]
The Zeta(z) Nontrivial zeros are related to the count of prime numbers.
I drawed the Zeta(z) curve. but it is strange. Do you know how to draw the following left image?
And that was all it was needed to it create a zeta visualizer in C. Then, as i said, i used the generated code in x for fine tune and fix it.
Hi,zedd/guga/jack
Thanks your help.
Quite useful information.
I am very interested in your Zeta algorithms. I need to learn hardly.
Zeta(z)=1/1^z+1/2^z+1/3^z+...+1/n^z+...
=1/(1-1/2^z) * 1/(1-1/3^z) * 1/(1-1/5^z) * 1/(1-1/7^z) * 1/(1-1/11^z) * ... * 1/(1-1/p^z)
n: All natural numbers
z = a+bi, a != 1
p = All prime numbers
ln(Zeta(z)) = -[ln(1-1/2^z)+ln(1-1/3^z)+ln(1-1/5^z)+ln(1-1/7^z)+...+ln(1-1/p^z)]
= x
Zeta(z) = e^x
150 years ago, no computer, the great mathematicians used their pens to calculate the Zeta(z) Nontrivial zeros. That's a very difficult job. Admiring!
The problem with the previous images was due to the step value being too large.
now it works fine.
Hi Six_L you´re welcome.
Now, try this. (Added zoom with mouse wheel and pg up/down), also it starts (resets) with a space and not only the R key
// ZetaVisualizerFinal.c - Added Page Up/Page Down zoom, smoothed curve, fixed starting line
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>
#include <math.h>
#include <stdio.h>
#include <time.h>
#include <commdlg.h>
#include <vector>
#pragma comment(lib, "gdiplus.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")
using namespace Gdiplus;
// Global variables for animation and zoom
static float animationProgress = 0.0f; // 0.0 to 1.0
static const float ANIMATION_SPEED = 0.005f; // Adjust for faster/slower animation
static const UINT_PTR ANIMATION_TIMER_ID = 1;
static bool isAnimationRunning = false; // Track animation state
static float zoomFactor = 1.0f; // Zoom factor (1.0 = default, >1 zoom in, <1 zoom out)
// Complex number structure
typedef struct {
double real;
double imag;
} Complex;
// Complex arithmetic functions
Complex ComplexAdd(Complex a, Complex b) {
Complex result;
result.real = a.real + b.real;
result.imag = a.imag + b.imag;
return result;
}
Complex ComplexMul(Complex a, Complex b) {
Complex result;
result.real = a.real * b.real - a.imag * b.imag;
result.imag = a.real * b.imag + a.imag * b.real;
return result;
}
Complex ComplexSub(Complex a, Complex b) {
Complex result;
result.real = a.real - b.real;
result.imag = a.imag - b.imag;
return result;
}
Complex ComplexPowReal(Complex base, double exponent) {
double r = sqrt(base.real * base.real + base.imag * base.imag);
double theta = atan2(base.imag, base.real);
double ln_r = log(r);
double exponent_ln_r = exponent * ln_r;
double exponent_theta = exponent * theta;
Complex result;
result.real = exp(exponent_ln_r) * cos(exponent_theta);
result.imag = exp(exponent_ln_r) * sin(exponent_theta);
return result;
}
Complex ComplexPow(Complex base, Complex exponent) {
double r = sqrt(base.real * base.real + base.imag * base.imag);
double theta = atan2(base.imag, base.real);
Complex ln_base;
ln_base.real = log(r);
ln_base.imag = theta;
Complex exponent_ln_base = ComplexMul(exponent, ln_base);
double magnitude = exp(exponent_ln_base.real);
Complex result;
result.real = magnitude * cos(exponent_ln_base.imag);
result.imag = magnitude * sin(exponent_ln_base.imag);
return result;
}
Complex ComplexDiv(Complex a, Complex b) {
double denom = b.real * b.real + b.imag * b.imag;
Complex result;
result.real = (a.real * b.real + a.imag * b.imag) / denom;
result.imag = (a.imag * b.real - a.real * b.imag) / denom;
return result;
}
Complex ComplexScale(Complex a, double scalar) {
Complex result;
result.real = a.real * scalar;
result.imag = a.imag * scalar;
return result;
}
Complex ComplexNeg(Complex a) {
Complex result;
result.real = -a.real;
result.imag = -a.imag;
return result;
}
// Complex logarithm: ln(z) = ln(|z|) + i * arg(z)
Complex ComplexLn(Complex z) {
Complex result;
result.real = log(sqrt(z.real * z.real + z.imag * z.imag));
result.imag = atan2(z.imag, z.real);
return result;
}
// Generate prime numbers using Sieve of Eratosthenes
std::vector<int> GeneratePrimes(int limit) {
std::vector<bool> isPrime(limit + 1, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i <= limit; i++) {
if (isPrime[i]) {
for (int j = i * i; j <= limit; j += i) {
isPrime[j] = false;
}
}
}
std::vector<int> primes;
for (int i = 2; i <= limit; i++) {
if (isPrime[i]) {
primes.push_back(i);
}
}
return primes;
}
// Zeta function using Euler product: ζ(z) = exp(-∑_p ln(1 - p^(-z)))
Complex Zeta(Complex z, int iterations) {
static std::vector<int> primes;
if (primes.empty()) {
primes = GeneratePrimes(1000);
}
Complex sum = { 0.0, 0.0 };
Complex one = { 1.0, 0.0 };
Complex p_complex, p_neg_z, term;
int count = 0;
for (int p : primes) {
if (count >= iterations) break;
p_complex.real = (double)p;
p_complex.imag = 0.0;
Complex neg_z = ComplexNeg(z);
p_neg_z = ComplexPow(p_complex, neg_z);
term = ComplexSub(one, p_neg_z);
Complex ln_term = ComplexLn(term);
sum = ComplexAdd(sum, ComplexNeg(ln_term));
count++;
}
double magnitude = exp(sum.real);
Complex result;
result.real = magnitude * cos(sum.imag);
result.imag = magnitude * sin(sum.imag);
return result;
}
// Draw the enhanced Zeta function visualization
void DrawEnhancedZeta(HDC hdc, int width, int height, float progress) {
Graphics graphics(hdc);
graphics.SetSmoothingMode(SmoothingModeAntiAlias);
graphics.SetCompositingQuality(CompositingQualityHighQuality);
graphics.SetTextRenderingHint(TextRenderingHintAntiAlias);
// Dark gradient background
LinearGradientBrush background(
Point(0, 0),
Point(width, height),
Color(255, 10, 20, 50),
Color(255, 0, 0, 0));
graphics.FillRectangle(&background, 0, 0, width, height);
// Set up coordinate system
REAL centerX = width / 2.0f;
REAL centerY = height / 2.0f;
REAL scale = (REAL)min(width, height) / 4.0f;
REAL unitScale = (scale / 12.0f) * zoomFactor; // Adjusted with zoom factor
// Draw subtle grid lines (step of 4 units)
Pen gridPen(Color(50, 100, 100, 150), 0.3f);
// Horizontal axis: Im(ζ(s)), up to ±32
for (int i = -8; i <= 8; i++) { // ±32, step 4
REAL gridPos = i * 4 * unitScale;
graphics.DrawLine(&gridPen,
0.0f, centerY + gridPos,
(REAL)width, centerY + gridPos);
}
// Vertical axis: Re(ζ(s)), up to ±24
for (int i = -6; i <= 6; i++) { // ±24, step 4
REAL gridPos = i * 4 * unitScale;
graphics.DrawLine(&gridPen,
centerX + gridPos, 0.0f,
centerX + gridPos, (REAL)height);
}
// Draw glowing axes
LinearGradientBrush axisBrush(
Point(0, (int)centerY),
Point(width, (int)centerY),
Color(150, 200, 200, 255),
Color(50, 100, 100, 100));
Pen axisPen(&axisBrush, 1.8f);
graphics.DrawLine(&axisPen, 0.0f, centerY, (REAL)width, centerY);
graphics.DrawLine(&axisPen, centerX, 0.0f, centerX, (REAL)height);
// Draw critical line
LinearGradientBrush criticalBrush(
Point((int)centerX, 0),
Point((int)centerX, height),
Color(150, 255, 150, 50),
Color(50, 100, 255, 50));
Pen criticalPen(&criticalBrush, 2.0f);
REAL criticalX = centerX + scale * 0.5f;
graphics.DrawLine(&criticalPen, criticalX, 0.0f, criticalX, (REAL)height);
// Compute Zeta function points and store them
const int iterations = 200;
const double t_start = 0.0;
const double t_end = 30.0;
const double t_step = 0.02;
double t_max = t_start + progress * (t_end - t_start);
// Collect points for the curve
std::vector<PointF> points;
for (double t = t_start; t <= t_max; t += t_step) {
Complex s = { 0.5, t };
Complex zeta = Zeta(s, iterations);
REAL x = centerX + (REAL)zeta.imag * unitScale;
REAL y = centerY - (REAL)zeta.real * unitScale;
points.push_back(PointF(x, y));
}
// Draw the Zeta curve as a smooth spline
GraphicsPath path;
if (!points.empty()) {
path.AddCurve(points.data(), (INT)points.size(), 0.5f); // Tension = 0.5 for smoothness
}
// Neon gradient for Zeta curve
Color colors[] = {
Color(200, 255, 50, 50),
Color(200, 255, 165, 0),
Color(200, 255, 0, 255),
Color(200, 50, 50, 255)
};
REAL positions[] = { 0.0f, 0.33f, 0.67f, 1.0f };
LinearGradientBrush pathBrush(
Point(0, (int)(centerY - scale)),
Point(0, (int)(centerY + scale)),
Color(255, 255, 255, 255),
Color(255, 255, 255, 255));
pathBrush.SetInterpolationColors(colors, positions, 4);
// Draw glow and main curve
Pen glowPen(&pathBrush, 5.0f);
glowPen.SetColor(Color(100, 255, 255, 255));
graphics.DrawPath(&glowPen, &path);
Pen zetaPen(&pathBrush, 2.5f);
graphics.DrawPath(&zetaPen, &path);
// Add annotations with adjusted positions
Font font(L"Cambria Math", 16, FontStyleBold);
Font smallFont(L"Cambria Math", 12, FontStyleRegular);
SolidBrush shadowBrush(Color(80, 0, 0, 0));
SolidBrush textBrush(Color(255, 230, 230, 230));
StringFormat format;
format.SetAlignment(StringAlignmentCenter);
// Title: "ζ(s) where s = ½ + ti"
Font bigFont(L"Cambria Math", 20, FontStyleBold);
graphics.DrawString(L"ζ(s) where s = ½ + ti", -1, &bigFont,
PointF(centerX + 4.0f, 24.0f), &format, &shadowBrush);
graphics.DrawString(L"ζ(s) where s = ½ + ti", -1, &bigFont,
PointF(centerX, 20.0f), &format, &textBrush);
// Critical line label: "Re(s) = ½"
graphics.DrawString(L"Re(s) = ½", -1, &font,
PointF(criticalX + 4.0f, 60.0f), &format, &shadowBrush);
graphics.DrawString(L"Re(s) = ½", -1, &font,
PointF(criticalX, 56.0f), &format, &textBrush);
// Axis label: "Im(ζ(s))"
REAL imLabelX = (REAL)width - 100.0f;
graphics.DrawString(L"Im(ζ(s))", -1, &font,
PointF(imLabelX + 4.0f, centerY - 24.0f), &shadowBrush);
graphics.DrawString(L"Im(ζ(s))", -1, &font,
PointF(imLabelX, centerY - 20.0f), &textBrush);
// Axis label: "Re(ζ(s))"
graphics.DrawString(L"Re(ζ(s))", -1, &font,
PointF(centerX + 14.0f, (REAL)height - 44.0f), &shadowBrush);
graphics.DrawString(L"Re(ζ(s))", -1, &font,
PointF(centerX + 10.0f, (REAL)height - 40.0f), &textBrush);
// Coordinate labels for horizontal axis (Im(ζ(s))): -32 to 32, step 4
for (int i = -8; i <= 8; i++) {
int value = i * 4;
REAL xPos = centerX + value * unitScale;
WCHAR label[16];
swprintf(label, 16, L"%d", value);
graphics.DrawString(label, -1, &smallFont,
PointF(xPos + 2.0f, centerY + 16.0f), &format, &shadowBrush);
graphics.DrawString(label, -1, &smallFont,
PointF(xPos, centerY + 12.0f), &format, &textBrush);
}
// Coordinate labels for vertical axis (Re(ζ(s))): -24 to 24, step 4
StringFormat nearFormat;
nearFormat.SetAlignment(StringAlignmentNear);
for (int i = -6; i <= 6; i++) {
int value = i * 4;
REAL yPos = centerY - value * unitScale;
WCHAR label[16];
if (value == 0) {
swprintf(label, 16, L"0");
}
else {
swprintf(label, 16, L"%di", value);
}
graphics.DrawString(label, -1, &smallFont,
PointF(centerX - 30.0f + 2.0f, yPos + 2.0f), &nearFormat, &shadowBrush);
graphics.DrawString(label, -1, &smallFont,
PointF(centerX - 30.0f, yPos), &nearFormat, &textBrush);
}
// Add animated non-trivial zero markers
double zeros[] = { 14.1347, 21.0220, 25.0109, 30.4249 };
int numZeros = sizeof(zeros) / sizeof(zeros[0]);
for (int i = 0; i < numZeros; i++) {
if (zeros[i] <= t_max) {
Complex s = { 0.5, zeros[i] };
Complex zeta = Zeta(s, iterations);
REAL x = centerX + (REAL)zeta.imag * unitScale;
REAL y = centerY - (REAL)zeta.real * unitScale;
LinearGradientBrush zeroBrush(
Point((int)(x - 10.0f), (int)(y - 10.0f)),
Point((int)(x + 10.0f), (int)(y + 10.0f)),
Color(200, 255, 100, 100),
Color(0, 255, 255, 255));
graphics.FillEllipse(&zeroBrush, x - 7.0f, y - 7.0f, 14.0f, 14.0f);
Pen zeroPen(Color(150, 255, 255, 255), 1.0f);
graphics.DrawEllipse(&zeroPen, x - 7.0f, y - 7.0f, 14.0f, 14.0f);
}
}
}
// Helper function to get PNG encoder CLSID
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) {
UINT num = 0, size = 0;
Gdiplus::GetImageEncodersSize(&num, &size);
if (size == 0) return -1;
ImageCodecInfo* pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
Gdiplus::GetImageEncoders(num, size, pImageCodecInfo);
for (UINT j = 0; j < num; ++j) {
if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0) {
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j;
}
}
free(pImageCodecInfo);
return -1;
}
// Save visualization as PNG
void SaveAsPng(HWND hWnd, int width, int height, const WCHAR* filename) {
Bitmap bitmap(width, height, PixelFormat32bppARGB);
Graphics bitmapGraphics(&bitmap);
bitmapGraphics.SetSmoothingMode(SmoothingModeAntiAlias);
bitmapGraphics.SetCompositingQuality(CompositingQualityHighQuality);
bitmapGraphics.SetTextRenderingHint(TextRenderingHintAntiAlias);
HDC hdc = bitmapGraphics.GetHDC();
DrawEnhancedZeta(hdc, width, height, 1.0f);
bitmapGraphics.ReleaseHDC(hdc);
CLSID clsid;
if (GetEncoderClsid(L"image/png", &clsid) != -1) {
bitmap.Save(filename, &clsid, NULL);
char msg[512];
snprintf(msg, sizeof(msg), "Visualization saved as %S", filename);
MessageBoxA(hWnd, msg, "Success", MB_OK | MB_ICONINFORMATION);
}
else {
MessageBoxA(hWnd, "Failed to save PNG: PNG encoder not found", "Error", MB_OK | MB_ICONERROR);
}
}
// Open file dialog for saving PNG
void ShowSaveDialog(HWND hWnd, int width, int height) {
WCHAR filename[MAX_PATH] = L"ZetaVisualization.png";
OPENFILENAMEW ofn = { 0 };
ofn.lStructSize = sizeof(OPENFILENAMEW);
ofn.hwndOwner = hWnd;
ofn.lpstrFilter = L"PNG Files (*.png)\0*.png\0All Files (*.*)\0*.*\0";
ofn.lpstrFile = filename;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrDefExt = L"png";
ofn.Flags = OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
if (GetSaveFileNameW(&ofn)) {
SaveAsPng(hWnd, width, height, filename);
}
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
static int width, height;
switch (message) {
case WM_CREATE:
break;
case WM_TIMER:
if (wParam == ANIMATION_TIMER_ID) {
animationProgress += ANIMATION_SPEED;
if (animationProgress > 1.0f) {
animationProgress = 1.0f;
KillTimer(hWnd, ANIMATION_TIMER_ID);
isAnimationRunning = false;
}
InvalidateRect(hWnd, NULL, FALSE);
}
break;
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
RECT rect;
GetClientRect(hWnd, &rect);
width = rect.right;
height = rect.bottom;
HDC memDC = CreateCompatibleDC(hdc);
HBITMAP memBitmap = CreateCompatibleBitmap(hdc, width, height);
HBITMAP oldBitmap = (HBITMAP)SelectObject(memDC, memBitmap);
HBRUSH blackBrush = (HBRUSH)GetStockObject(BLACK_BRUSH);
FillRect(memDC, &rect, blackBrush);
DrawEnhancedZeta(memDC, width, height, animationProgress);
BitBlt(hdc, 0, 0, width, height, memDC, 0, 0, SRCCOPY);
SelectObject(memDC, oldBitmap);
DeleteObject(memBitmap);
DeleteDC(memDC);
EndPaint(hWnd, &ps);
break;
}
case WM_SIZE:
width = LOWORD(lParam);
height = HIWORD(lParam);
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_MOUSEWHEEL: {
short delta = GET_WHEEL_DELTA_WPARAM(wParam);
float zoomStep = 1.1f;
if (delta > 0) {
// Scroll up: Zoom in
zoomFactor *= zoomStep;
if (zoomFactor > 3.0f) zoomFactor = 3.0f;
}
else if (delta < 0) {
// Scroll down: Zoom out
zoomFactor /= zoomStep;
if (zoomFactor < 0.5f) zoomFactor = 0.5f;
}
InvalidateRect(hWnd, NULL, FALSE);
break;
}
case WM_COMMAND:
switch (LOWORD(wParam)) {
case 1001:
ShowSaveDialog(hWnd, width, height);
break;
case 1002:
if (!isAnimationRunning) {
SetTimer(hWnd, ANIMATION_TIMER_ID, 16, NULL);
isAnimationRunning = true;
}
break;
case 1003:
if (isAnimationRunning) {
KillTimer(hWnd, ANIMATION_TIMER_ID);
isAnimationRunning = false;
}
break;
}
break;
case WM_KEYDOWN:
switch (wParam) {
case 'R': // Reset animation
case VK_SPACE: // Also reset with Space key
animationProgress = 0.0f;
if (!isAnimationRunning) {
SetTimer(hWnd, ANIMATION_TIMER_ID, 16, NULL);
isAnimationRunning = true;
}
InvalidateRect(hWnd, NULL, FALSE);
break;
case VK_PRIOR: // Page Up: Zoom in
zoomFactor *= 1.1f;
if (zoomFactor > 3.0f) zoomFactor = 3.0f;
InvalidateRect(hWnd, NULL, FALSE);
break;
case VK_NEXT: // Page Down: Zoom out
zoomFactor /= 1.1f;
if (zoomFactor < 0.5f) zoomFactor = 0.5f;
InvalidateRect(hWnd, NULL, FALSE);
break;
}
break;
case WM_DESTROY:
if (isAnimationRunning) {
KillTimer(hWnd, ANIMATION_TIMER_ID);
}
PostQuitMessage(0);
break;
default:
return DefWindowProcA(hWnd, message, wParam, lParam);
}
return 0;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
HMENU hMenu = CreateMenu();
HMENU hFileMenu = CreatePopupMenu();
AppendMenuA(hFileMenu, MF_STRING, 1001, "Save As...");
AppendMenuA(hFileMenu, MF_STRING, 1002, "Start Animation");
AppendMenuA(hFileMenu, MF_STRING, 1003, "Pause Animation");
AppendMenuA(hMenu, MF_POPUP, (UINT_PTR)hFileMenu, "File");
WNDCLASSA wc = { 0 };
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = "ZetaVisualizer";
wc.hCursor = LoadCursorA(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
RegisterClassA(&wc);
HWND hWnd = CreateWindowA("ZetaVisualizer", "Riemann Zeta Function Visualizer",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
1200, 900, NULL, hMenu, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
MSG msg;
while (GetMessageA(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
DestroyMenu(hMenu);
GdiplusShutdown(gdiplusToken);
return (int)msg.wParam;
}
Full project on this link: https://www.mediafire.com/file/kbwfvysh83cc33x/Zeta14.rar/file (https://www.mediafire.com/file/kbwfvysh83cc33x/Zeta14.rar/file)
(https://i.postimg.cc/V085wLYK/Zeta-Visualization.png) (https://postimg.cc/V085wLYK)
Hi,guga
good works!
:thumbsup:
I want to compare your image. Could you post an image of the following parameters?
step = 0.012
a = 1/2,b = [-1025.4712,-1015.1512]
Scale = 50:1
iterations = 860
Thank you in advance.
Regards
six_L
A test project for pure C with Pelles C.
Just for testing those functions, no graphics.
I updated my FreeBasic code
the Riemann zeta function (https://www.freebasic.net/forum/viewtopic.php?p=193860#p193860) now supports both negative and complex arguments
there's a bug in there somewhere, zeta(-20.1) gives the wrong sign, other than that the value is ok
the complex cosine is giving the wrong sign, any trig experts here?
fixed
sample output
Dim As complex x, y, z
Dim As Double rr, ri
for rr=-1 to 1 step .5
for ri=-1 to 1 step .5
x=complex(rr, ri)
y=zeta(x)
print using "zeta(##.####, ##.####) = ";x.re;x.im;
print using "##.################, ##.################";y.re;y.im
next
next
zeta(-1.0000, -1.0000) = 0.0168761517881836, 0.1141564804323963
zeta(-1.0000, -0.5000) = -0.0538894302820935, 0.0752004260118382
zeta(-1.0000, 0.0000) = -0.0833333333333334, 0.0000000000000000
zeta(-1.0000, 0.5000) = -0.0538894302820935, -0.0752004260118382
zeta(-1.0000, 1.0000) = 0.0168761517881836, -0.1141564804323963
zeta(-0.5000, -1.0000) = -0.0008178931340101, 0.2230716886972805
zeta(-0.5000, -0.5000) = -0.1407574606243030, 0.1580763818474494
zeta(-0.5000, 0.0000) = -0.2078862249773547, 0.0000000000000000
zeta(-0.5000, 0.5000) = -0.1407574606243030, -0.1580763818474494
zeta(-0.5000, 1.0000) = -0.0008178931340101, -0.2230716886972805
zeta( 0.0000, -1.0000) = 0.0033002236853245, 0.4181554491413226
zeta( 0.0000, -0.5000) = -0.2991978789224703, 0.3593711792648014
zeta( 0.0000, 0.0000) = -0.4999999999999991, 0.0000000000000000
zeta( 0.0000, 0.5000) = -0.2991978789224703, -0.3593711792648014
zeta( 0.0000, 1.0000) = 0.0033002236853245, -0.4181554491413226
zeta( 0.5000, -1.0000) = 0.1439364270771889, 0.7220997435316735
zeta( 0.5000, -0.5000) = -0.4593028903460181, 0.9612542845058791
zeta( 0.5000, 0.0000) = -1.4603545088095850, 0.0000000000000000
zeta( 0.5000, 0.5000) = -0.4593028903460181, -0.9612542845058791
zeta( 0.5000, 1.0000) = 0.1439364270771889, -0.7220997435316735
zeta( 1.0000, -1.0000) = 0.5821580597520036, 0.9268485643308069
zeta( 1.0000, -0.5000) = 0.5784330210993112, 1.9635494964529780
zeta( 1.0000, 0.0000) = -1.#IND000000000000, -1.#IND000000000000
zeta( 1.0000, 0.5000) = 0.5784330210993112, -1.9635494964529780
zeta( 1.0000, 1.0000) = 0.5821580597520036, -0.9268485643308069
Hi,TimoVJL/jack
Thanks for sharing.
Here have the Zeta(z) 7 Nontrivial zeros.
(https://i.postimg.cc/PfLWhPXD/3.png) (https://postimages.org/)
The Zeta(z) Nontrivial Zero looks like this(Attachment).
And what was code for it ?
Long time ago i asked form mathematician, can he show me a mathematical functions for best woman breasts and butts.
I have seen many functions for those and some of them are really good.
For woman breast some GDI functions are very good simulating those things, but sadly those sources aren't availble right now.
Quote from: TimoVJL on May 15, 2025, 12:59:26 AMAnd what was code for it ?
I'll ask an even better question...
"Where is the
assembly code for
any of it?", even if it is only uasm compatible and not specifically masm compatible (given the board that it is in).
Enquiring minds want to know... :badgrin:
For me, it's just despatching my interesting time when I have excess energy.
But the question of finding prime is very mysterious.
I guess:
Every Riemann Zeta(z) Nontrivial Zero corresponds to a prime number.
Zeta(0.5+bi) = 0
f(0.5+bi) = p
The larget known maxiprime today is 2^136279841-1. If someone finds the function, we'll find the next maxiprime to be easy.
QuoteLong time ago i asked form mathematician, can he show me a mathematical functions for best woman breasts and butts.
I have seen many functions for those and some of them are really good.
For woman breast some GDI functions are very good simulating those things, but sadly those sources aren't availble right now.
This is a best APP, ought to continue.
I was interest, how Complex numbers are handled in pure masm.
Complex numbers are part of C since C99, not supported by Pelles C anymore.
Hi,
Quote from: TimoVJL on May 15, 2025, 07:33:29 PMI was interest, how Complex numbers are handled in pure masm.
I do not think there is any direct support for complex, or imaginary,
arithmetic in MASM. You would have to implement such actions as macros
or a set of functions. So you would handle complex numbers with your
own code.
Of course, someone has probably done this already, and you could use
their implementation.
Regards,
Steve N.
Quote from: TimoVJL on May 15, 2025, 12:59:26 AMAnd what was code for it ?
Long time ago i asked form mathematician, can he show me a mathematical functions for best woman breasts and butts.
I have seen many functions for those and some of them are really good.
For woman breast some GDI functions are very good simulating those things, but sadly those sources aren't availble right now.
Seen on TV show a woman named "fern",but there is also exist code for draw a fern plant
Might be possible with combine several curves used for creating meshes
I only have managed to created sphere with trigo curves: 1700 half circles drawing a planet,also made an egg shape
Hourglass body = vertical cosine
In C11 specs _Complex data type is just optional.
So many C programmers are now in same position as asm programmers.
@daydreamer, jokes needs their own topic and this is UAsm topic and i was asking masm way to handle complex numbers.
Quote from: TimoVJL on May 16, 2025, 09:41:30 PMIn C11 specs _Complex data type is just optional.
So many C programmers are now in same position as asm programmers.
@daydreamer, jokes needs their own topic and this is UAsm topic and i was asking masm way to handle complex numbers.
I think math expert raymond might have something in his math library ???
QuoteI was interest, how Complex numbers are handled in pure masm.
for example:
FpuPow proc @Fx:QWORD,@Fy:QWORD
;return: ST(0)=x^y
;x^y =2^[y*log2(x)], x > 0
finit
mov rax,@Fy
fld tbyte ptr[rax] ;y
mov rax,@Fx
fld tbyte ptr[rax] ;x,x11=x11^y
fyl2x ;y*log2(x)
;ST(0)=y*log2(x), ST(1)=zzz
fld st ;make a second copy
;ST(0)=y*log2(x), ST(1)=y*log2(x), ST(2)=zzz
frndint ;round it to an integer
;ST(0)=int[y*log2(x)], ST(1)=y*log2(x), ST(2)=zzz
fsub st(1),st ;this will leave only a fractional portion in ST(1)
;ST(0)=int[y*log2(x)], ST(1)=y*log2(x)-int[y*log2(x)], ST(2)=zzz
fxch st(1) ;ST(0)=y*log2(x)-int[y*log2(x)], ST(1)=int[y*log2(x)], ST(2)=zzz
f2xm1 ;get the fractional power of 2 (minus 1)
;ST(0)=2ST(0)-1, ST(1)=int[y*log2(x)], ST(2)=zzz
fld1 ;ST(0)=1, ST(1)=2ST(0)-1, ST(2)=int[y*log2(x)], ST(3)=zzz
fadd ;add the 1 to ST(1) and POP ST(0)
;ST(0)=2ST(0), ST(1)=int[y*log2(x)], ST(2)=zzz
fscale ;add the integer in ST(1) to the exponent of ST(0)
;effectively multiplying the content of ST(0) by 2int
;and yielding the final result of x^y
;ST(0)=x^y, ST(1)=int[y*log2(x)], ST(2)=zzz
fstp st(1) ;the content of ST(1) has become useless
;overwrite the content of ST(1) with the result and POP ST(0)
;ST(0)=x^y, ST(1)=zzz
ret
FpuPow endp
;¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
EComplexNumberPow proc @inRealPart:QWORD,@inImaginaryPart:QWORD,@OutRealPart:QWORD,@OutImaginaryPart:QWORD
LOCAL @e:REAL10
; e^(a+bi)
; i = (-1)^0.5
; e^(a+bi) = e^a * e^[b*ln(e)i] = e^a * [cos(b.ln(e))] + e^a * [sin(b.ln(e))]i
; = e^a * [cos(b)] + e^a * [sin(b)]i
finit
; e^a
fld FP10(2.7182818284590452)
fstp @e
invoke FpuPow, addr @e, @inRealPart ; e^a
mov rax,@inImaginaryPart
fld tbyte ptr [rax] ; b
fsincos ; st0=cos(b),st1=sin(b)
fmul st(0),st(2) ; e^a * cos(b)
mov rax,@OutRealPart
fstp tbyte ptr [rax] ; @OutRealPart = e^a * cos(b)
fmul st(0),st(1) ; e^a * sin(b)
mov rax,@OutImaginaryPart
fstp tbyte ptr [rax] ; @OutImaginaryPart = e^a * sin(b)
ffree st(0)
ret
EComplexNumberPow endp
LOCAL ao:REAL10
LOCAL bo:REAL10
LOCAL a:REAL10
LOCAL b:REAL10
fld FP10(0.3)
fstp a
fld FP10(0.4)
fstp b
; e^(0.3+0.4i)
invoke EComplexNumberPow,addr a,addr b,addr ao,addr bo
; Print
; ( 1.243302295069503) + ( 0.525659779196979)i
; ao = 1.243302295069503
; bo = 0.525659779196979
Hi six_L
if you need some reference code here's a reasonably complete set of functions complex Riemann Zeta (https://www.freebasic.net/forum/viewtopic.php?p=193860#p193860)
Thanks six_L :thumbsup:
I used it for test code for poasm.exe V13
Hi,jack
Thanks you.
' f(k)=(k+nc)^-n
' inf nc inf inf
' ==== ==== / ==== B
' \ 1 \ 1 [ \ (2*k) (2*k-1)
' > ----- = > ----- + I f(k) dk + B * f(0) - > ------ f (0)
' / n / n ] 1 / (2*k)!
' ==== k ==== k / ====
' k = 1 k = 1 0 k = 1
I don't understand your Zeta formula. Do you have some detailed documentations about the formula?
1, Maybe some mistakes in calculation.
Quotezeta( 1.0000, -1.0000) = 0.5821580597520036, 0.9268485643308069
zeta( 1.0000, -0.5000) = 0.5784330210993112, 1.9635494964529780
zeta( 1.0000, 0.0000) = -1.#IND000000000000, -1.#IND000000000000
zeta( 1.0000, 0.5000) = 0.5784330210993112, -1.9635494964529780
zeta( 1.0000, 1.0000) = 0.5821580597520036, -0.9268485643308069
Quotezeta( 1.0000, -1.0000) = inf
zeta( 1.0000, -0.5000) = inf
zeta( 1.0000, 0.0000) = inf
zeta( 1.0000, 0.5000) = inf
zeta( 1.0000, 1.0000) = inf
Gamma(s).Gamma(1-s) = Pi/sin(s.Pi) ; Euler Product.
Zeta(s) = [1/(2.pi.i)].Gamma(1-s).Int_(+inf --> +inf)[(z^(s-1).e^z)/(1-e^z)].dz ; Riemann Product.
i = (-1)^0.5
s = a + bi ; a != 1
pay attention to the (+inf --> +inf):
+inf --> ... --> (0~) --> ... --> +inf , It's not the Int_(0 --> +inf) or Int_(-inf --> +inf)
Zeta(s) = 2.Gamma(1-s).(2Pi)^(s-1).sin(Pi.s/2).Zeta(1-s)
2, some of nontrivial zeros in Riemann Zeta Function:
Quote1, ( 0.5 + 14.1347251 i ) ; 11, ( 0.5 - 14.1347251 i )
2, ( 0.5 + 21.0220396 i ) ; 12, ( 0.5 - 21.0220396 i )
3, ( 0.5 + 25.0108575 i ) ; 13, ( 0.5 - 25.0108575 i )
4, ( 0.5 + 30.4248761 i ) ; 14, ( 0.5 - 30.4248761 i )
5, ( 0.5 + 32.9350615 i ) ; 15, ( 0.5 - 32.9350615 i )
6, ( 0.5 + 37.5861781 i ) ; 16, ( 0.5 - 37.5861781 i )
7, ( 0.5 + 40.9187190 i ) ; 17, ( 0.5 - 40.9187190 i )
8, ( 0.5 + 43.3270732 i ) ; 18, ( 0.5 - 43.3270732 i )
9, ( 0.5 + 48.0051508 i ) ; 19, ( 0.5 - 48.0051508 i )
10,( 0.5 + 49.7738324 i ) ; 20, ( 0.5 - 49.7738324 i )
Zeta_1(s) is the aux function of Zeta(s).
Zeta_1(s) = Pi^(-s/2).Gamma(s/2).Zeta(s)
of which:
Pi^(-s/2).Gamma(s/2) is the Euler Factor.
if we want to get the Zero of Zeta(s), we need to get the Zero of Zeta_1(1-s).
for example:
Zeta(0.5+14.1 i) --> Zeta_1[1-(0.5+14.1 i)] --> Zeta_1(0.5-14.1 i)
because getting the Zero of Zeta_1(1-s) value is more easier than the Zero of Zeta(s), and the Zeros of Zeta_1(1-s) is equal the Zeros of Zeta(s).
3, Reflecting Function
Zeta(s) = 2.Gamma(1-s).(2Pi)^(s-1).sin(Pi.s/2).Zeta(1-s)
if we use (1-s) to replace the s. then the result is swaping left and right.
QuoteGamma(s).Gamma(1-s) = Pi/sin(s.Pi)
sin(2a) = 2sin(a).cos(a)
sin(a-b) = sin(a).cos(b) - cos(a).sin(b)
Zeta(1-s) = 2.Gamma(1-(1-s)).(2Pi)^((1-s)-1).sin(Pi.(1-s)/2).Zeta(1-(1-s))
= 2.Gamma(s).(2Pi)^(-s).sin((Pi/2)-(Pi.s/2)).Zeta(s) ;sin(Pi.(1-s)/2)
= 2.Gamma(s).(2Pi)^(-s).[sin(Pi/2).cos(Pi.s/2)-cos(Pi/2).sin(Pi.s/2)].Zeta(s) ;sin(Pi/2)=1, cos(Pi/2)=0
= 2.Gamma(s).(2Pi)^(-s).cos(Pi.s/2).Zeta(s) ;Gamma(s) = Pi/[sin(s.Pi).Gamma(1-s)]
= 2.(Pi/[sin(s.Pi).Gamma(1-s)]).(2Pi)^(-s).cos(Pi.s/2).Zeta(s)
= ((2Pi).(2Pi)^(-s).cos(Pi.s/2)/[sin(s.Pi).Gamma(1-s)]).Zeta(s) ;(2Pi).(2Pi)^(-s)=(2Pi)^(1-s)
= ((2Pi)^(1-s).cos(Pi.s/2)/[sin(s.Pi).Gamma(1-s)]).Zeta(s)
= (cos(Pi.s/2)/[(2Pi)^(s-1).sin(s.Pi).Gamma(1-s)]).Zeta(s) ;(2Pi)^(1-s)= (2Pi)^[-(s-1)]
Zeta(1-s).(2Pi)^(s-1).sin(s.Pi).Gamma(1-s)/cos(Pi.s/2) = Zeta(s) ;y=(a/b).x -->(b/a).y=x
[Gamma(1-s).(2Pi)^(s-1).sin(s.Pi)/cos(Pi.s/2)].Zeta(1-s) = Zeta(s) ;
sin(s.Pi)/cos(Pi.s/2)=sin[2(s.Pi/2)]/cos(Pi.s/2) ;sin(2a) = 2sin(a).cos(a)
=[2.sin(Pi.s/2).cos(Pi.s/2)]/cos(Pi.s/2)
=2.sin(Pi.s/2)
[Gamma(1-s).(2Pi)^(s-1).sin(s.Pi)/cos(Pi.s/2)].Zeta(1-s) = Zeta(s)
[Gamma(1-s).(2Pi)^(s-1).2.sin(Pi.s/2)].Zeta(1-s) = Zeta(s)
2.Gamma(1-s).(2Pi)^(s-1).sin(Pi.s/2).Zeta(1-s) = Zeta(s) ;swaped left and right.
4, the progress in prime number researching.
4.1 Adjacent prime numbers
2,3,5,7,11,13,17,...
3-2=1,17-13=4,...
p(n+1)-p(n) < 2460000 ;This means the max gap of any prime numbers less than 2460000.
4.2 there are the 45% nontrivial zeros on 1/2 line.(the attachment paper)
5,the features of Riemann Zeta function's nontrivial zeros
5.1 Count
Zeta(s)=Zeta(a+bi)=0
i = (-1)^0.5
s = a + bi ; a != 1, a = 1/2, real b > 0
CountZeros[-b,b] = 2[(b/2Pi).ln(b/2Pi) - (b/2Pi) + O(ln(b))]
5.2 Distribution
The distribution features of nontrivial zeros is similar to the quantum energy level.
6, more precision at the nontrivial zeros in Riemann Zeta(s) Function
a = 1/2, real b > 0
accurate to over 1000 decimal places.
Quote14.134725141734693790457251983562470270784257115699243175685567460149
9634298092567649490103931715610127792029715487974367661426914698822545
8250536323944713778041338123720597054962195586586020055556672583601077
3700205410982661507542780517442591306254481978651072304938725629738321
5774203952157256748093321400349904680343462673144209203773854871413783
1735639699536542811307968053149168852906782082298049264338666734623320
0787587617920056048680543568014444246510655975686659032286865105448594
4432062407272703209427452221304874872092412385141835146054279015244783
3835425453344004487936806761697300819000731393854983736215013045167269
6838920039176285123212854220523969133425832275335164060169763527563758
9695376749203361272092599917304270756830879511844534891800863008264831
2516911271068291052375961797743181517071354531677549515382893784903647
4709727019948485532209253574357909226125247736595518016975233461213977
3160053541259267474557258778014726098308089786007125320875093959979666
60675378381214891908864977277554420656532052405
21.022039638771554992628479593896902777334340524902781754629520403587
5985860688907997136585141801514195337254736424758913838650686037313212
6211882162437574166925654471184407119403130672564622779261488733743555
2059147397132822662470789076753814440726466841906077127569834054514028
4399232225367882682361112892700575856532731588666042140009071151080090
0697200279987110175847519632216496865900574811247938691638351837234278
0734490239101038504575641215958399921001621834669113158721748057170315
7935817977249632724076992211256634415618236051804767144227146555596737
8124776500455584090864429169775704638165517749644524987674237036645657
7704837992029270664315837893238009151146858070430828784147861992007607
7604774841407827389070038957604332451278278637209093037972518237091808
0423066673834379902282515828788761761266187138296785874562376500666242
0780814517636976391374340593412797549697276850306200263121273830462939
3025654143823744333440220248004533438830728387312602306547534837868011
82789317520010690056016544152811050970637593228
25.010857580145688763213790992562821818659549672557996672496542006745
0920984416442778402382245580624407504710461490557783782998515227308011
8813393358267168958722516981043873551292849372719199462297591267547869
6628856807735070039957723114023284276873669399873219586487752250099192
4534749762085766123345997354435583675313812659977645290374484969947911
3789772206619930718997232254973227163005159161921279774087660006729149
8308127930667027350849516001984670542469491796695225514179319665391273
4145216731602337377544894146417119378489574997514110658562879690076709
8628272186495372963239258403491387143048933588946114958624239036855617
5189359878735685683089271444468756375337019130417377142535868018531867
8963753268686326607197669205329533478506707982877118674944281439725425
5165319679779912722684458969279408599507227960513612021369680647653397
6269691774251249095257214003855886494422730332216278403670865759210329
0789866156020484275192735141927597017849166084411074821559128310749314
22640278339513428773126644105168571016344289902
30.424876125859513210311897530584091320181560023715440180962146036993
3293893332779202905842939020891106309917115273954991176332266711863193
9180722595671424334115590685468136558072417349844724959319040811632315
0197023484841630221400985620739718392018133021868063298225719752250023
7468561369747124964426229779245040574906715345727886515065160832468797
0628177810457777225878919237386290011276030973568089049253006461289272
7530919447902003589389819427495511323917384271638108400499211198006924
3871887296959700029100054774270689081684625934838507707996560373392659
1631785900558390596815720730796252620549400959515892318195507003120438
5472912847073737931700052460469858203860095171051337905912538151203525
6495480686539474573064428698419890124742762009249476736375814720332208
6687601457265777407119672734350479234503516187981145579444869326121291
4417916583251901867849867644777729648215979712565041026341481014213352
4013338332668144856154491448771220118284070765164762211312808070237683
31017097022722833154052850963731871619582513781