class_docstr: Attacks a model with word substiutitions using a Particle Swarm
  Optimization (PSO) algorithm. Some key hyper-parameters are setup according
  to the original paper:
  
  "We adjust PSO on the validation set of SST and set ω_1 as 0.8 and ω_2 as 0.2.
  We set the max velocity of the particles V_{max} to 3, which means the changing
  probability of the particles ranges from 0.047 (sigmoid(-3)) to 0.953 (sigmoid(3))."
  
  Args:
      pop_size (:obj:`int`, optional): The population size. Defaults to 60.
      max_iters (:obj:`int`, optional): The maximum number of iterations to use. Defaults to 20.
      post_turn_check (:obj:`bool`, optional): If `True`, check if new position reached by moving passes the constraints. Defaults to `True`
      max_turn_retries (:obj:`bool`, optional): Maximum number of movement retries if new position after turning fails to pass the constraints.
          Applied only when `post_movement_check` is set to `True`.
          Setting it to 0 means we immediately take the old position as the new position upon failure.
class_docstr_tok: ["Attacks","a","model","with","word","substiutitions","using","a","Particle","Swarm","Optimization","(","PSO",")","algorithm",".","Some","key","hyper-parameters","are","setup","according","to","the","original","paper",":","''","We","adjust","PSO","on","the","validation","set","of","SST","and","set","\u03c9_1","as","0.8","and","\u03c9_2","as","0.2",".","We","set","the","max","velocity","of","the","particles","V_","{","max","}","to","3",",","which","means","the","changing","probability","of","the","particles","ranges","from","0.047","(","sigmoid","(","-3",")",")","to","0.953","(","sigmoid","(","3",")",")",".","''","Args",":","pop_size","(",":","obj",":","`","int","`",",","optional",")",":","The","population","size",".","Defaults","to","60.","max_iters","(",":","obj",":","`","int","`",",","optional",")",":","The","maximum","number","of","iterations","to","use",".","Defaults","to","20.","post_turn_check","(",":","obj",":","`","bool","`",",","optional",")",":","If","`","True","`",",","check","if","new","position","reached","by","moving","passes","the","constraints",".","Defaults","to","`","True","`","max_turn_retries","(",":","obj",":","`","bool","`",",","optional",")",":","Maximum","number","of","movement","retries","if","new","position","after","turning","fails","to","pass","the","constraints",".","Applied","only","when","`","post_movement_check","`","is","set","to","`","True","`",".","Setting","it","to","0","means","we","immediately","take","the","old","position","as","the","new","position","upon","failure","."]
docstr: Based on given probabilities, "move" to `target_text` from `source_text`
  Args:
      source_text (PopulationMember): Text we start from.
      target_text (PopulationMember): Text we want to move to.
      prob (np.array[float]): Turn probability for each word.
      original_text (AttackedText): Original text for constraint check if `self.post_turn_check=True`.
  Returns:
      New `Position` that we moved to (or if we fail to move, same as `source_text`)
docstr_tok: ["Based","on","given","probabilities",",","``","move","''","to","`","target_text","`","from","`","source_text","`","Args",":","source_text","(","PopulationMember",")",":","Text","we","start","from",".","target_text","(","PopulationMember",")",":","Text","we","want","to","move","to",".","prob","(","np.array","[","float","]",")",":","Turn","probability","for","each","word",".","original_text","(","AttackedText",")",":","Original","text","for","constraint","check","if","`","self.post_turn_check=True","`",".","Returns",":","New","`","Position","`","that","we","moved","to","(","or","if","we","fail","to","move",",","same","as","`","source_text","`",")"]
code: def _turn(self, source_text, target_text, prob, original_text):
      """
      Based on given probabilities, "move" to `target_text` from `source_text`
      Args:
          source_text (PopulationMember): Text we start from.
          target_text (PopulationMember): Text we want to move to.
          prob (np.array[float]): Turn probability for each word.
          original_text (AttackedText): Original text for constraint check if `self.post_turn_check=True`.
      Returns:
          New `Position` that we moved to (or if we fail to move, same as `source_text`)
      """
      assert len(source_text.words) == len(
          target_text.words
      ), "Word length mismatch for turn operation."
      assert len(source_text.words) == len(
          prob
      ), "Length mismatch for words and probability list."
      len_x = len(source_text.words)
  
      num_tries = 0
      passed_constraints = False
      while num_tries < self.max_turn_retries + 1:
          indices_to_replace = []
          words_to_replace = []
          for i in range(len_x):
              if np.random.uniform() < prob[i]:
                  indices_to_replace.append(i)
                  words_to_replace.append(target_text.words[i])
          new_text = source_text.attacked_text.replace_words_at_indices(
              indices_to_replace, words_to_replace
          )
          indices_to_replace = set(indices_to_replace)
          new_text.attack_attrs["modified_indices"] = (
              source_text.attacked_text.attack_attrs["modified_indices"]
              - indices_to_replace
          ) | (
              target_text.attacked_text.attack_attrs["modified_indices"]
              & indices_to_replace
          )
          if (
              "last_transformation"
              in source_text.attacked_text.attack_attrs
          ):
              new_text.attack_attrs[
                  "last_transformation"
              ] = source_text.attacked_text.attack_attrs[
                  "last_transformation"
              ]
  
          if not self.post_turn_check or (
              new_text.words == source_text.words
          ):
              break
  
          if "last_transformation" in new_text.attack_attrs:
              passed_constraints = self._check_constraints(
                  new_text,
                  source_text.attacked_text,
                  original_text=original_text,
              )
          else:
              passed_constraints = True
  
          if passed_constraints:
              break
  
          num_tries += 1
  
      if self.post_turn_check and not passed_constraints:
          # If we cannot find a turn that passes the constraints, we do not move.
          return source_text
      else:
          return PopulationMember(new_text)
  
file_path: TextAttack/textattack/search_methods/particle_swarm_optimization.py
imports: import copy
  import numpy
  from textattack.goal_function_results import GoalFunctionResultStatus
  from textattack.search_methods import PopulationBasedSearch, PopulationMember
  from textattack.shared import utils
  from textattack.shared.validators import transformation_consists_of_word_swaps
label_desc: Use image node_id 4 for calling the ParticleSwarmOptimization obj's underlying member method code with example usage: obj._turn(source_text, target_text, prob, original_text) and returns: source_text, PopulationMember