private void ScreenClicked(object sender, EventArgs e) { var ClickPos = ScreenBox.PointToClient(Cursor.Position); bool Verify = VerifyRect.Contains(ClickPos); ClickPos = new Point(ClickPos.X + FrameRect.X, ClickPos.Y + FrameRect.Y); BrowserHost.ExecuteClick(ClickPos); if (Verify) { LoadingMode(true); ThreadTools.Wait(3000, true); if (IsCaptchaSolved()) { Close(); } else { UpdateRects(); LoadingMode(false); } } else { StatusCheck.Enabled = false; StatusCheck.Enabled = true; Clicks++; } }
public static void WaitInitialize(this CefSharp.WinForms.ChromiumWebBrowser Browser) { while (!Browser.IsBrowserInitialized) { ThreadTools.Wait(5, true); } }
void Initialize() { Application.DoEvents(); LoadingMode(true); Refresh.Enabled = true; if (!v3 || hCaptcha) { var Thread = new System.Threading.Thread(() => { ResetCaptcha(); ThreadTools.Wait(1500); ClickImNotRobot(); }); Thread.Start(); while (Thread.IsRunning()) { ThreadTools.Wait(5, true); } UpdateRects(); } else { Submit(); UpdateRects(); } LoadingMode(false); System.Media.SystemSounds.Beep.Play(); StatusCheck.Enabled = true; }
private void OnValidate() { if (WriteImageToBase) { WriteImageToBase = false; ThreadTools.StartCoroutine(writeAsBase64()); } if (WriteUrls) { WriteUrls = false; ThreadTools.StartCoroutine(writToCor()); } if (TestRawImage) { TestRawImage = false; ThreadTools.StartCoroutine(testImage()); } // Google Drive // foreach (var item in modelUrlLists.Urls) // { // if (!string.IsNullOrEmpty(item.Url)) // { // // parse // item.Url = item.Url.Replace("open?id", "uc?export=download&id"); // } // } }
public ComicInfo LoadUri(Uri Uri) { if (Browser == null) { Browser = new ChromiumWebBrowser(); Browser.Size = new System.Drawing.Size(500, 600); Browser.ReCaptchaHook(); while (!Browser.IsBrowserInitialized) { ThreadTools.Wait(100, true); } Login(); SkipSlowDown(); SolveCaptcha(); } CurrentUrl = Uri.AbsoluteUri; var Document = DownloadDocument(Uri); ComicInfo Info = new ComicInfo(); Info.Title = HttpUtility.HtmlDecode(Document.Descendants("title").First().InnerText); Info.Title = DataTools.GetRawName(Info.Title).Split('»').First(); Info.Cover = TryDownload(new Uri(HttpUtility.HtmlDecode(Document .SelectSingleNode("//div[@id=\"cover\"]/a/img") .GetAttributeValue("data-src", "")))); Info.ContentType = ContentType.Comic; return(Info); }
private void OnValidate() { if (objectPoint != null) { objectPoint.position = new Vector3(point.x, point.y, 0); } if (rightBorder != null && leftBorder != null && @base != null && guessHeightObject != null) { @base.position = AsRight * width / 2; @base.localScale = new Vector3(width, @base.localScale.y, @base.localScale.z); guessHeightObject.localScale = new Vector3(width, guessHeightObject.localScale.y, guessHeightObject.localScale.z); guessHeightObject.position = @base.position + AsUp * guessHeight; rightBorder.position = leftBorder.position + AsRight * width; } if (test1) { test1 = false; ThreadTools.StartCoroutine(delayStart(() => TryCalcalate())); } if (testAngle) { testAngle = false; ThreadTools.StartCoroutine(delayStart(() => TestAngle())); } if (testReal) { testReal = false; ThreadTools.StartCoroutine(delayStart(() => TestCalculateRealPos())); } }
public void Init() { if (isInitialized) { return; } isInitialized = true; ThreadTools.Initialize(); List <IServices> currentServices = new List <IServices> { sceneService, jsonConverter, webLoader, new DownloadAssetBundles() }; List <IController> controllers = new List <IController> { new DownloadMetaDataFromFirebase() }; App.Start(currentServices, controllers); // Init only after the App starts foreach (var item in controllers) { item.Init(null, null); } if (gameObject.scene.name.Equals(sceneService.Scenes[1])) { return; } App.Services.SceneService.LoadSceneWithVideo(1, null, 2); }
public void Init() { if (isInitialized) { return; } isInitialized = true; ThreadTools.Initialize(); List <IServices> currentServices = new List <IServices> { sceneService, jsonConverter }; List <IController> controllers = new List <IController> { // new DownloadController(), }; App.Start(currentServices, controllers); // Init only after the App starts foreach (var item in controllers) { item.Init(); } if (gameObject.scene.name.Equals(sceneService.Scenes[1])) { return; } App.SceneService.LoadSceneWithVideo(1, null, 2); }
private void StatusCheckTick(object sender, EventArgs e) { if (IsCaptchaSolved()) { Close(); return; } if (IsCaptchaFailed()) { ResetCaptcha(); ThreadTools.Wait(500); if (Submit != null) { Submit(); ThreadTools.Wait(500, true); } Close(); return; } if (Clicks > 0) { Clicks--; UpdateRects(); RefreshTick(null, null); } }
public bool LoadSceneWithVideo(string nextScene, IReadOnlyList <GameObject> hideInTransition = null, float fadeTime = 1.0f) { if (m_state != State.Inactive) { return(false); } currentTime = 0; m_nextScene = nextScene; m_video.enabled = true; m_fade = 1 / (fadeTime * 0.5f); m_video.isLooping = true; m_camera.enabled = true; m_video.targetCamera = m_camera; m_video.targetCameraAlpha = 0.0f; m_video.isLooping = true; m_video.Play(); m_state = State.FadeIn; m_hideTheseWhenActivated = hideInTransition; ThreadTools.StartCoroutine(UpdateCoroutine()); return(true); }
public static void WaitForLoad(this IBrowser Browser) { ThreadTools.Wait(100); while (Browser.IsLoading()) { ThreadTools.Wait(5, true); } }
public static void ExecuteMove(this IBrowserHost Browser, List <MimicStep> Steps) { foreach (var Step in Steps) { Browser.SendMouseMoveEvent(new MouseEvent(Step.Location.X, Step.Location.Y, CefEventFlags.None), false); ThreadTools.Wait(Step.Delay); } }
public static void WaitForLoad(this IFrame Frame) { ThreadTools.Wait(100); while (Frame.IsLoading()) { ThreadTools.Wait(5, true); } }
public static CloudflareData BypassCloudflare(this string Url) { var Status = Main.Status; Main.Status = Main.Language.BypassingCloudFlare; var Browser = DefaultBrowser.GetBrowser(); DefaultBrowser.JsDialogHandler = new JsDialogHandler(); DefaultBrowser.Load(Url); Browser.WaitForLoad(); while (Browser.IsCloudflareTriggered()) { ThreadTools.Wait(100, true); Browser.WaitForLoad(); } if (Browser.GetHTML().Contains("why_captcha_headline")) { while (Browser.IsCloudflareTriggered() || Browser.IsCloudflareAskingCaptcha()) { if (!DefaultBrowser.ReCaptchaIsSolved()) { DefaultBrowser.ReCaptchaTrySolve(Main.Solver); EvaluateScript(Properties.Resources.CloudFlareSubmitCaptcha); } if (!DefaultBrowser.hCaptchaIsSolved()) { DefaultBrowser.hCaptchaSolve(); ThreadTools.Wait(1000, true); } ThreadTools.Wait(1000, true); Browser.WaitForLoad(); } } Browser.WaitForLoad(); var HTML = Browser.GetHTML(); var Cookies = Browser.GetCookies().ToContainer(); DefaultBrowser.Load("about:blank"); Main.Status = Status; if (Program.Debug) { Program.Writer?.WriteLine("CF Bypass Result: {0}\r\nHTML: {1}", Browser.MainFrame.Url, HTML); } return(new CloudflareData() { Cookies = Cookies, UserAgent = Browser.GetUserAgent(), HTML = HTML }); }
public static void ReCaptchaSolveSound(this ChromiumWebBrowser ChromiumBrowser, string Response, Point CursorPos, out Point NewCursorPos) { var BHost = ChromiumBrowser.GetBrowserHost(); var Browser = ChromiumBrowser.GetBrowser(); var BFrame = Browser.ReCaptchaGetBFrame(); NewCursorPos = CursorPos; //Get Sound Reponse Textbox Position var Result = (string)BFrame.EvaluateScriptAsync(Properties.Resources.reCaptchaGetSoundResponsePosition).GetAwaiter().GetResult().Result; if (Result == null) { return; } Random Random = new Random(); int X = int.Parse(DataTools.ReadJson(Result, "x").Split('.', ',')[0]); int Y = int.Parse(DataTools.ReadJson(Result, "y").Split('.', ',')[0]); //Parse the relative position of the iframe to Window Point BFramePos = Browser.ReCaptchaGetBFramePosition(); Point RespBoxPos = new Point(X + BFramePos.X + Random.Next(5, 100), Y + BFramePos.Y + Random.Next(5, 15)); //Create Macro var Move = CursorTools.CreateMove(CursorPos, RespBoxPos, 6); //Execute Macro BHost.ExecuteMove(Move); ThreadTools.Wait(Random.Next(999, 1999), true); BHost.ExecuteClick(RespBoxPos); ThreadTools.Wait(Random.Next(511, 999), true); foreach (char Char in Response) { BHost.SendChar(Char); } //Get Verify Button Position var VerifyBntRect = Browser.ReCaptchaGetVerifyButtonRectangle(); //Parse the relative position of the iframe to Window Point VerifyBntPos = new Point(VerifyBntRect.X + BFramePos.X + Random.Next(5, 40), VerifyBntRect.Y + BFramePos.Y + Random.Next(5, 15)); //Create and Execute Macro Move = CursorTools.CreateMove(RespBoxPos, VerifyBntPos, 6); BHost.ExecuteMove(Move); ThreadTools.Wait(Random.Next(999, 1999), true); BHost.ExecuteClick(VerifyBntPos); NewCursorPos = VerifyBntPos; ThreadTools.Wait(Random.Next(3599, 4599), true); }
public IEnumerable <byte[]> DownloadPages(int ID) { CurrentUrl = LinkMap[ID]; string Link = GetNextPage(); int Reaming = GetChapterPageCount(ID); Browser.Load(Link); Browser.WaitForLoad(); string Last = null; do { Uri PLink = null; while (PLink == null) { ThreadTools.Wait(100, true); if (!Browser.ReCaptchaIsSolved()) { Browser.ReCaptchaTrySolve(Main.Solver); Browser.EvaluateScript("document.getElementsByClassName(\"auth-page\")[0].getElementsByTagName(\"form\")[0].submit();"); Browser.WaitForLoad(); Cookies = Browser.GetCookies().ToContainer(); } if (Browser.Address.Split('#').First() != Link && !Browser.Address.Contains("Read/Auth")) { Browser.Load(Link); Browser.WaitForLoad(); } var Document = Browser.GetDocument(); var Node = Document.SelectSingleNode("//img[@class=\"img-responsive reader-img\"]"); if (Node == null) { continue; } var HREF = Node.GetAttributeValue("src", null); if (HREF == null || HREF == Last) { continue; } Last = HREF; PLink = HREF.EnsureAbsoluteUri(Domain); } Link = GetNextPage(Link); Browser.EvaluateScript("gotoNextPage();"); yield return(TryDownload(PLink)); } while (--Reaming > 0); }
public static void SendChar(this IBrowserHost Browser, char Char) { Browser.SendKeyEvent(new KeyEvent() { FocusOnEditableField = true, IsSystemKey = false, Modifiers = CefEventFlags.None, WindowsKeyCode = Char, Type = KeyEventType.Char }); ThreadTools.Wait(random.Next(40, 100)); }
public static void hCaptchaClickImHuman(this IBrowser Browser, out Point Cursor) { var Rnd = new Random(); var Begin = new Point(Rnd.Next(5, 25), Rnd.Next(5, 25)); var Target = Browser.GethCaptchaImHumanButtonPosition(); var Move = CursorTools.CreateMove(Begin, Target, MouseSpeed: 10); Browser.ExecuteMove(Move); ThreadTools.Wait(Rnd.Next(100, 150), true); Browser.ExecuteClick(Target); ThreadTools.Wait(Rnd.Next(500, 650), true); Cursor = Target; }
public static bool ReCaptchaClickImNotRobot(this ChromiumWebBrowser ChromiumBrowser, out Point NewCursorPos) { var BHost = ChromiumBrowser.GetBrowserHost(); var Browser = ChromiumBrowser.GetBrowser(); Random Random = new Random(); ThreadTools.Wait(Random.Next(999, 1999), true); //Get Recaptcha Position in the page var Result = (string)Browser.MainFrame.EvaluateScriptAsync(Properties.Resources.reCaptchaIframeSearch + "\r\n" + Properties.Resources.reCaptchaGetAnchorPosition).GetAwaiter().GetResult().Result; int X = int.Parse(DataTools.ReadJson(Result, "x").Split('.', ',')[0]); int Y = int.Parse(DataTools.ReadJson(Result, "y").Split('.', ',')[0]); int Width = int.Parse(DataTools.ReadJson(Result, "width").Split('.', ',')[0]); int Height = int.Parse(DataTools.ReadJson(Result, "height").Split('.', ',')[0]); //Create Positions Point InitialPos = new Point(Random.Next(15, 20), Random.Next(25, 30)); Point CaptchaClick = new Point(X + Random.Next(15, 20), Y + Random.Next(15, 20)); var CaptchaRegion = new Rectangle(X, Y, Width, Height); Point PostClick = new Point(CaptchaRegion.Right + Random.Next(-10, 10), Y + Random.Next(-10, 10)); //Ensure the fake click don't will click in the "i'm not a robot" Point?FakeClick = null; while (FakeClick == null || CaptchaRegion.Contains(FakeClick.Value)) { FakeClick = new Point(Random.Next(10, 500), Random.Next(20, 500)); } //Create Macros var MoveA = CursorTools.CreateMove(InitialPos, FakeClick.Value); var MoveB = CursorTools.CreateMove(FakeClick.Value, CaptchaClick); var MoveC = CursorTools.CreateMove(CaptchaClick, PostClick); //Execute Macros BHost.ExecuteMove(MoveA); ThreadTools.Wait(Random.Next(999, 1999), true); BHost.ExecuteClick(FakeClick.Value); BHost.ExecuteMove(MoveB); ThreadTools.Wait(Random.Next(999, 1999), true); BHost.ExecuteClick(CaptchaClick); BHost.ExecuteMove(MoveC); NewCursorPos = PostClick; ThreadTools.Wait(Random.Next(3599, 4599), true); return(Browser.ReCaptchaIsSolved()); }
private void SkipSlowDown() { Browser.Load(CurrentUrl); Browser.GetBrowser().WaitForLoad(); bool SlowDown = Browser.GetBrowser().GetHTML().Contains("You're loading pages way too quickly"); if (SlowDown) { Browser.GetBrowser().EvaluateScript("document.getElementsByClassName(\"button button-wide\")[0].click();"); ThreadTools.Wait(1000, true); Browser.GetBrowser().WaitForLoad(); } }
public void Deform(Vector3 impactVector, Vector3 simplifiedVector) { Deform_local(impactVector, simplifiedVector, mFilter.sharedMesh); ThreadTools.WaitForThreads(ref threads); threads.Clear(); mFilter.sharedMesh.vertices = thread_vertices; mFilter.sharedMesh.RecalculateBounds(); Deform_local(impactVector, simplifiedVector, simplifiedMesh); ThreadTools.WaitForThreads(ref threads); threads.Clear(); simplifiedMesh.vertices = thread_vertices; UpdateMeshCollider(); }
private void ManageFileUids(XamlFileDescription xamlFileDescription) { using (var textReader = visualStudioAdapter.GetXamlFileContent(xamlFileDescription)) { var uidCollector = new UidManager(xamlFileDescription.Name, textReader, localizabilityChecker).ParseFileSmart(); if (uidCollector.Count > 0) { switch (ManageUidOperation) { case ManageUidOperation.CheckUid: var fvm = new XamlFileViewModel(solutionFolder, xamlFileDescription, uidCollector); ThreadTools.InvokeInUIThread(Window, () => InvalidFiles.Add(fvm)); break; case ManageUidOperation.UpdateUid: if (!uidCollector.AllAreValid()) { //TODO: resolve duplicates UpdateFileUids(xamlFileDescription, uidCollector); var fvm1 = new XamlFileViewModel(solutionFolder, xamlFileDescription, null); ThreadTools.InvokeInUIThread(Window, () => InvalidFiles.Add(fvm1)); } break; case ManageUidOperation.RemoveUid: if (!uidCollector.AllAreAbsent()) { UpdateFileUids(xamlFileDescription, uidCollector); var fvm2 = new XamlFileViewModel(solutionFolder, xamlFileDescription, null); ThreadTools.InvokeInUIThread(Window, () => InvalidFiles.Add(fvm2)); } break; case ManageUidOperation.PrepareTranslation: bamlResourceCollector.Add(xamlFileDescription, uidCollector); break; default: throw new ArgumentOutOfRangeException(); } } } }
private static bool Retry(Action Operation, int Times = 3) { try { Operation.Invoke(); return(true); } catch { ThreadTools.Wait(1000, true); if (Times >= 0) { return(Retry(Operation, Times - 1)); } return(false); } }
public static void ReCaptchaClickAudioChallenge(this ChromiumWebBrowser ChromiumBrowser, Point CursorPos, out Point NewCursorPos) { var BHost = ChromiumBrowser.GetBrowserHost(); var Browser = ChromiumBrowser.GetBrowser(); var BFrame = Browser.ReCaptchaGetBFrame(); NewCursorPos = CursorPos; if (Browser.ReCaptchaIsFailed()) { return; } Random Random = new Random(); //Get Audio Challenge Button Pos var Result = (string)BFrame.EvaluateScriptAsync(Properties.Resources.reCaptchaGetSpeakPosition).GetAwaiter().GetResult().Result; int X = int.Parse(DataTools.ReadJson(Result, "x").Split('.', ',')[0]); int Y = int.Parse(DataTools.ReadJson(Result, "y").Split('.', ',')[0]); int Width = int.Parse(DataTools.ReadJson(Result, "width").Split('.', ',')[0]); int Height = int.Parse(DataTools.ReadJson(Result, "height").Split('.', ',')[0]); Point AudioBntPos = new Point(X + Random.Next(5, Width - 5), Y + Random.Next(5, Height - 5)); //Parse the relative position of the iframe to Window Point BFramePos = Browser.ReCaptchaGetBFramePosition(); AudioBntPos = new Point(AudioBntPos.X + BFramePos.X, AudioBntPos.Y + BFramePos.Y); //Create and Execute the Macro var Move = CursorTools.CreateMove(CursorPos, AudioBntPos, 7); BHost.ExecuteMove(Move); ThreadTools.Wait(Random.Next(999, 1999), true); BHost.ExecuteClick(AudioBntPos); ThreadTools.Wait(Random.Next(2111, 3599), true); NewCursorPos = AudioBntPos; }
private bool SolveCaptcha() { Browser.Load(CurrentUrl); Browser.GetBrowser().WaitForLoad(); if (!Browser.GetBrowser().GetHTML().Contains("<h1>Really, slow down</h1>")) { return(false); } if (Browser.GetBrowser().ReCaptchaIsSolved()) { return(false); } Browser.ReCaptchaTrySolve(Main.Solver); Browser.GetBrowser().EvaluateScript("document.forms[0].submit();"); ThreadTools.Wait(1000, true); Browser.GetBrowser().WaitForLoad(); return(true); }
public void Deform(int meshIndex) { if (meshIndex > bMeshes.Length - 1) { return; } thread_pts = new Vector3[bMeshes[meshIndex].origVerts.Length]; BendParameters bp = new BendParameters(); bp.N = ts_transform.TransformDirection(1, 0, 0); bp.BiN = ts_transform.TransformDirection(0, 0, -1); bp.T = ts_transform.TransformDirection(0, 1, 0); bp.bendEnd = ts_targetTransform.TransformPoint(0, length, 0); int start = (direction) ? 0 : bMeshes[meshIndex].seperatingIndex; int end = (direction) ? bMeshes[meshIndex].seperatingIndex : bMeshes[meshIndex].origVerts.Length; for (int i = start; i < end; i += maxWorkGroupSize) { int workgroupSize = (i + maxWorkGroupSize < bMeshes[meshIndex].origVerts.Length) ? maxWorkGroupSize : bMeshes[meshIndex].origVerts.Length - i; threads.Add(StartThread(i, i + workgroupSize, ts_transform, ts_targetTransform, bp, meshIndex)); } start = (direction) ? bMeshes[meshIndex].seperatingIndex : 0; end = (direction) ? bMeshes[meshIndex].origVerts.Length : bMeshes[meshIndex].seperatingIndex; for (int i = start; i < end; i++) { thread_pts[i] = bMeshes[meshIndex].origVerts[i]; } ThreadTools.WaitForThreads(ref threads); bMeshes[meshIndex].mesh.vertices = thread_pts; }
/// <summary> /// Try Solve the Captcha, And request the user help if needed. /// </summary> /// <param name="OBrowser">The Browser Instance With the Captcha</param> public static void ReCaptchaTrySolve(this ChromiumWebBrowser OBrowser, CaptchaSolverType SolverType = CaptchaSolverType.SemiAuto) { var Browser = OBrowser.GetBrowser(); Browser.WaitForLoad(); ThreadTools.Wait(1500, true); if (SolverType != CaptchaSolverType.Manual) { if (!Browser.ReCaptchaIsSolved()) { Point Cursor = new Point(0, 0); do { OBrowser.ReCaptchaClickImNotRobot(out Cursor); if (Browser.ReCaptchaIsSolved()) { return; } } while (Browser.ReCaptchaGetBFramePosition().Y == BFrameHidden); for (int i = 0; i < 3 && !Browser.ReCaptchaIsSolved(); i++) { try { if (Browser.ReCaptchaIsFailed()) { Browser.ReCaptchaReset(); if (Browser.ReCaptchaIsSolved()) { break; } } } catch { } try { OBrowser.ReCaptchaClickAudioChallenge(Cursor, out Cursor); if (Browser.ReCaptchaIsFailed()) { continue; } var Response = Browser.DecodeAudioChallenge(); if (Response == null) { continue; } OBrowser.ReCaptchaSolveSound(Response, Cursor, out Cursor); } catch (Exception ex) { if (!Browser.ReCaptchaIsSolved()) { throw ex; } else { break; } } } } } if (Browser.ReCaptchaIsSolved()) { return; } do { using (var Solver = new SolveCaptcha(OBrowser)) Solver.ShowDialog(); } while (!Browser.ReCaptchaIsSolved()); }
public static void Factorise(int K, int M, int N, float[,] V, float[,] W, float[,] H, int ITERATIONS) { double[] rmses = new double[NUM_THREADS]; float[,] WH = new float[M, N]; // Random initialisation of W and H Tools.InitialiseRandomMatrices(K, M, N, W, H); // And now we iterate int iteration = 0; while (true) { Logging.Info("Iteration {0}", iteration); // Calculate the new WH (for efficiency reasons so we dont have to calc twice) { int num_threads_running = 0; for (int thread_id = 0; thread_id < NUM_THREADS; ++thread_id) { int thread_id_local = thread_id; ThreadTools.StartThread(o => PARALLEL_WH(K, M, N, V, W, H, WH, NUM_THREADS, thread_id_local, ref num_threads_running, rmses)); } Tools.WaitForThreads(ref num_threads_running); // Tally the RMSE double rmse = 0; for (int thread_id = 0; thread_id < NUM_THREADS; ++thread_id) { rmse += rmses[thread_id]; } rmse = Math.Sqrt(rmse); Logging.Info("Iteration {0} has an RMSE of {1}", iteration, rmse); } // Check exit condition ++iteration; if (iteration >= ITERATIONS) { break; } // Calculate the new P { int num_threads_running = 0; for (int thread_id = 0; thread_id < NUM_THREADS; ++thread_id) { int thread_id_local = thread_id; ThreadTools.StartThread(o => PARALLEL_H(K, M, N, V, W, H, WH, NUM_THREADS, thread_id_local, ref num_threads_running)); } Tools.WaitForThreads(ref num_threads_running); } // Calculate the new A { int num_threads_running = 0; for (int thread_id = 0; thread_id < NUM_THREADS; ++thread_id) { int thread_id_local = thread_id; ThreadTools.StartThread(o => PARALLEL_W(K, M, N, V, W, H, WH, NUM_THREADS, thread_id_local, ref num_threads_running)); } Tools.WaitForThreads(ref num_threads_running); } } }
private void Awake() { ThreadTools.Initialize(); lineRendererReal.useWorldSpace = true; lineRendererCalc.useWorldSpace = true; }
public static void Factorise(int K, int M, int N, float[,] V, float[,] W, float[,] H, int ITERATIONS) { double[] rmses = new double[NUM_THREADS]; float[,] WH = new float[M, N]; // Computational enhancement with sparse matrices MultiMap <int, int> M_sparse; MultiMap <int, int> N_sparse; FindSparseLocations(M, N, V, out M_sparse, out N_sparse); // Random initialisation of W and H Tools.InitialiseRandomMatrices(K, M, N, W, H); // And now we iterate int iteration = 0; while (true) { Logging.Info("Iteration {0}", iteration); // Calculate the new WH every now and then to check our progress... ++iteration; if (0 == iteration % 3) { int num_threads_running = 0; for (int thread_id = 0; thread_id < NUM_THREADS; ++thread_id) { int thread_id_local = thread_id; ThreadTools.StartThread(o => PARALLEL_WH(K, M, N, V, W, H, WH, NUM_THREADS, thread_id_local, ref num_threads_running, rmses)); } Tools.WaitForThreads(ref num_threads_running); // Tally the RMSE double rmse = 0; for (int thread_id = 0; thread_id < NUM_THREADS; ++thread_id) { rmse += rmses[thread_id]; } rmse = Math.Sqrt(rmse); Logging.Info("Iteration {0} has an RMSE of {1}", iteration, rmse); // Check exit condition if (iteration >= ITERATIONS) { break; } } // Calculate the new H { int num_threads_running = 0; for (int thread_id = 0; thread_id < NUM_THREADS; ++thread_id) { int thread_id_local = thread_id; ThreadTools.StartThread(o => PARALLEL_H(K, M, N, V, W, H, WH, M_sparse, N_sparse, NUM_THREADS, thread_id_local, ref num_threads_running)); } Tools.WaitForThreads(ref num_threads_running); } // Calculate the new W { int num_threads_running = 0; for (int thread_id = 0; thread_id < NUM_THREADS; ++thread_id) { int thread_id_local = thread_id; ThreadTools.StartThread(o => PARALLEL_W(K, M, N, V, W, H, WH, M_sparse, N_sparse, NUM_THREADS, thread_id_local, ref num_threads_running)); } Tools.WaitForThreads(ref num_threads_running); } } }